Cod sursa(job #1004733)

Utilizator geniucosOncescu Costin geniucos Data 3 octombrie 2013 16:45:45
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.55 kb
#include<queue>
#include<cstdio>
#include<vector>
using namespace std;
int n,m,nr,A,B,i,j,c1,c2,Q[400009],rmq[400009][20],t[100009],niv[100009],pr[100009],lg[400009];
/////////////////////////////////////////precalculari
vector < int > v[100009];
vector < int > :: iterator it;
queue < int > cc;
void euler(int nod)
{
    vector < int > :: iterator it;
    for(it=v[nod].begin();it!=v[nod].end();it++)
        {
            nr++;
            Q[nr]=nod;
            niv[*it]=niv[nod]+1;
            euler(*it);
        }
    nr++;
    Q[nr]=nod;
}
int QR(int st,int dr)
{
    int c1,c2,ex=lg[dr-st+1];
    c1=rmq[st][ex];
    c2=rmq[dr-(1<<ex)+1][ex];
    if(niv[c1]<niv[c2]) return c1;
    else return c2;
}
int LCA(int x,int y)
{
    if(pr[x]<pr[y]) return QR(pr[x],pr[y]);
    else return QR(pr[y],pr[x]);
}
int main()
{
freopen("lca.in","r",stdin);
freopen("lca.out","w",stdout);
scanf("%d",&n);
scanf("%d",&m);
for(i=2;i<=n;i++)
{
    scanf("%d",&t[i]);
    v[t[i]].push_back(i);
}
//////////////////////////////////////////////////precalculari
niv[1]=0;
euler(1);
for(i=1;i<=nr;i++)
    if(pr[Q[i]]==0) pr[Q[i]]=i;
for(i=1;i<=nr;i++)
{
    lg[i]=lg[i-1];
    if((1<<(lg[i]+1))<=i) lg[i]++;
}
for(i=nr;i>=1;i--)
{
    rmq[i][0]=Q[i];
    for(j=1;i+(1<<j)-1<=nr;j++)
    {
        c1=rmq[i][j-1];
        c2=rmq[i+(1<<(j-1))][j-1];
        if(niv[c1]<niv[c2]) rmq[i][j]=c1;
        else rmq[i][j]=c2;
    }
}
for(i=1;i<=m;i++)
{
    scanf("%d",&A);
    scanf("%d",&B);
    printf("%d\n",LCA(A,B));
}
return 0;
}