Cod sursa(job #581092)

Utilizator andrey932Andrei andrey932 Data 13 aprilie 2011 19:14:47
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.53 kb
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
#define MAXN 100005

ifstream fin("lca.in");
ofstream fout("lca.out");

vector<int> graf[MAXN];
int i,j,t[MAXN],n,m,a,b;
int euler[2*MAXN],euler_niv[2*MAXN],rmq[20][MAXN];

void preg_lca() {
    int prec;
    euler[1]=1;
    euler_niv[1]=1;
    rmq[0][1]=1;
    for(i=2;i<=2*n;i++) {
        prec=euler[i-1];
        if (!graf[prec].empty()) {
            euler[i]=graf[prec].back();
            graf[prec].pop_back();
            euler_niv[i]=euler_niv[i-1]+1;
        }
        else {
            euler[i]=t[prec];
            euler_niv[i]=euler_niv[i-1]+1;
        }
        rmq[0][i]=i;
    }

    for(i=1;(1<<i)<=2*n;i++) {
        for(j=1;j+(1<<i)<=2*n;j++) {
            if (euler_niv[rmq[i-1][j]]>=euler_niv[rmq[i-1][j+1<<(i-1)]]) {
                rmq[i][j]=rmq[i-1][j];
            }
            else {
                rmq[i][j]=rmq[i-1][j+1<<(i-1)];
            }
        }
    }
}

int rmqf(int a, int b) {
    int x=b-a+1,l=0;
    while (x>0) {l++; x>>=1;}
    if (euler_niv[rmq[l][a]]<=euler_niv[rmq[l][b-(1<<l)+1]]) {
        return rmq[l][a];
    }
    else return rmq[l][b-(1<<l)+1];
}

int lca(int x, int y) {
    int lc=rmqf(x,y);
    return euler[lc];
}






int main()
{
    fin>>n>>m;
    for(i=2;i<=n;i++) {
        fin>>t[i];
        graf[t[i]].push_back(i);
    }

    for(i=1;i<=m;i++) {
        fin>>a>>b;
        fout<<lca(a,b)<<"\n";
    }

    fout.close();
    return 0;
}