Cod sursa(job #1886869)

Utilizator silkMarin Dragos silk Data 21 februarie 2017 10:54:01
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.48 kb
#include <bits/stdc++.h>
#define NMax 200000
#define Log 18
using namespace std;

vector<int> a[NMax+1];
int rmq[Log+1][NMax+1];
int stiva[NMax+1];
int idx[NMax+1];
int ap[NMax+1];
int V[NMax+1];
int H[NMax+1];
int P[NMax+1];
int N,K;

void DFS()
{
    int x,vf;

    stiva[vf = 1] = 1;
    while(vf)
    {
        x = stiva[vf];
        V[++K] = x;
        H[x] = vf;
        if(idx[x] < a[x].size()) stiva[++vf] = a[x][ idx[x]++ ];
        else --vf;
    }
}

void Build()
{
    int i,j;

    for(i = 2; i <= NMax; ++i) P[i] = P[i/2] + 1;
    for(i = 1; i <= K; ++i) rmq[0][i] = V[i];
    for(i = 1; (1<<i) <= K; ++i)
        for(j = 1; j <= K-(1<<i)+1; ++j)
        {
            rmq[i][j] = rmq[i-1][j];
            if(H[ rmq[i-1][j+(1<<i-1)] ] < H[ rmq[i][j] ]) rmq[i][j] = rmq[i-1][j+(1<<i-1)];
        }
}

int main(){
    FILE* fin = fopen("lca.in","r");
    FILE* fout = fopen("lca.out","w");

    int i,k,x,y,lg,res,T;

    fscanf(fin,"%d %d",&N,&T);
    for(i = 2; i <= N; ++i)
    {
        fscanf(fin,"%d",&x);
        a[x].push_back(i);
    }

    DFS();
    Build();
    for(i = 1; i <= K; ++i)
    if(!ap[ V[i] ]) ap[ V[i] ] = i;

    while(T--)
    {
        fscanf(fin,"%d %d",&x,&y);
        x = ap[x];
        y = ap[y];
        if(x > y) swap(x,y);
        k = P[y-x+1];
        res = rmq[k][x];
        if(H[res] > H[ rmq[k][y+1-(1<<k)] ]) res = rmq[k][y+1-(1<<k)];
        fprintf(fout,"%d\n",res);
    }


return 0;
}