Cod sursa(job #1098081)

Utilizator misinozzz zzz misino Data 4 februarie 2014 13:55:36
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.22 kb
#include<fstream>
#include<vector>
#define N 200100
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
int n,m,i,j,l,lg,dif,p2,x,y,sol,niv[N],e[N],rmq[18][N],log[N],p[N];
vector<int>v[N];
inline void dfs(int x,int nivel)//Parcurgere Euler
{
    e[++lg]=x;
    niv[lg]=nivel;
    p[x]=lg;//prima aparitie
    for(vector<int>::iterator it=v[x].begin();it!=v[x].end();++it)
    {
        dfs(*it,nivel+1);
        e[++lg]=x;
        niv[lg]=nivel;
    }
}
int main()
{
    f>>n>>m;
    for(i=2;i<=n;++i)
    {
        f>>x;
        v[x].push_back(i);
    }
    dfs(1,0);
    //RMQ
    for(i=2;i<=lg;++i)
    log[i]=log[i>>1]+1;
    for(i=1;i<=lg;++i)
    rmq[0][i]=i;
    for(i=1,l=1;(1<<i)<lg;++i,l<<=1)
    for(j=1;j<=lg-(1<<i);++j)
    {
        rmq[i][j]=rmq[i-1][j];
        if(niv[rmq[i][j]]>niv[rmq[i-1][j+l]])
        rmq[i][j]=rmq[i-1][j+l];
    }
    //Rezolvare
    for(;m;--m)
    {
        f>>x>>y;
        x=p[x];
        y=p[y];
        if(x>y)
        swap(x,y);
        dif=y-x+1;
        l=log[dif];
        p2=dif-(1<<l);
        sol=rmq[l][x];
        if(niv[rmq[l][x+p2]]<niv[sol])
        sol=rmq[l][x+p2];
        g<<e[sol]<<'\n';
    }
    return 0;
}