Cod sursa(job #1369089)

Utilizator gabrielinelusGabriel-Robert Inelus gabrielinelus Data 2 martie 2015 21:41:05
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.04 kb
#include <cstdio>
#include <algorithm>
#include <vector>

#define Nmax 200105
#define DIM 3666013

#define adancime first
#define nod second

using namespace std;

char buffer[DIM];
int Poz = DIM - 1;

void Scanf(int &A){
    A = 0;
    while('0' > buffer[Poz] || buffer[Poz] > '9')
        if(++Poz == DIM)
            fread(buffer,1,DIM,stdin),Poz = 0;
    while('0' <= buffer[Poz] && buffer[Poz] <= '9'){
        A = A * 10 + buffer[Poz] - 48;
        if(++Poz == DIM)
            fread(buffer,1,DIM,stdin),Poz = 0;
    }
}

vector<vector<int> > G;
vector<int> poz;
pair<int,int> DP[18][Nmax];

int N,Q,pzc;

void Read(){
    Scanf(N);Scanf(Q);
    G.resize(N+1);
    poz.resize(N+1);
    int a;
    for(int i = 2; i <= N; ++i){
        Scanf(a);
        G[a].push_back(i);
    }
}

void DFS(int k,int depth){
    DP[0][++pzc] = make_pair(depth,k);
    for(vector<int>::iterator it = G[k].begin(); it != G[k].end(); ++it)
    {
        DFS(*it,depth+1);
        DP[0][++pzc] = make_pair(depth,k);
    }
}

void RMQ()
{
    int limi = 0,IT = 1;
    while( (1<<(limi+1)) < pzc )
        ++limi;
    for(int i = 1; i <= limi; ++i)
    {
        for(int j = 1; j <= pzc; ++j)
            if(j + IT > pzc)
                DP[i][j] = DP[i-1][j];
            else
                DP[i][j] = min(DP[i-1][j],DP[i-1][j+IT]);
        IT *= 2;
    }
}

int Query(int a,int b)
{
    int x , y;
    x = poz[a];
    y = poz[b];
    if(x > y)
        swap(x,y);
    int len = y - x + 1,IT = 1,lin = 0;
    while( (IT<<1) <= len )
        IT<<=1,++lin;
    return min(DP[lin][x],DP[lin][y - IT + 1]).second;
}

void Solve()
{
    DFS(1,0);
    for(int i = 1; i <= pzc; ++i)
        if(!poz[DP[0][i].nod])
            poz[DP[0][i].nod] = i;
    RMQ();
    int a,b;
    for(int i = 1; i <= Q; ++i){
        Scanf(a);Scanf(b);
        printf("%d\n",Query(a,b));
    }

}


int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);

    Read();
    Solve();

    return 0;
}