Cod sursa(job #1369067)

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

#define DIM 3666013
#define Nmax 100005
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;
    }
}

using namespace std;
int DP[18][Nmax];
int cmin[18][Nmax];
int depth[Nmax];
int N,Q;
vector<vector<int> > G;

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

void read()
{
    Scanf(N);Scanf(Q);
    G.resize(N+1);
    for(int i = 2; i <= N; ++i){
        Scanf(DP[0][i]);
        G[DP[0][i]].push_back(i);
    }
    DFS(1,1);
}

void dynamic()
{
    int li = 0;
    while( (1 <<(li+1)) <= N)
        ++li;
    DP[0][1] = 1;
    for(int i = 1; i <= li; ++i)
        for(int j = 1; j <= N; ++j)
            DP[i][j] = DP[i-1][DP[i-1][j]];
}

int get_ancestor(int k,int lv)
{
    int lim = 0;
    while((1<<(lim+1)) <= lv )
        ++lim;
    for(int i = 0; i <= lim; ++i)
        if(lv & (1<<lim))
        {
            lv ^= (1<<lim);
            k = DP[lim][k];
        }
    return k;
}

void solve()
{
    int a,b;
    for(int i = 1; i <= Q; ++i)
    {
        Scanf(a);Scanf(b);
        if(depth[a] < depth[b])
            swap(a,b);
        a = get_ancestor(a,depth[a] - depth[b]);
        if(a == b){
            printf("%d\n",a);
            continue;
        }
        int lim = 0;
        while( (1<<(lim+1)) <= depth[a])
            ++lim;
        for(int j = lim; j >= 0; --j)
            if(DP[j][a] != DP[j][b])
            {
                a = DP[j][a];
                b = DP[j][b];
            }
        printf("%d\n",DP[0][a]);
    }
}

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

    read();
    dynamic();
    solve();

    return 0;
}