Cod sursa(job #1827142)

Utilizator LucianTLucian Trepteanu LucianT Data 11 decembrie 2016 15:00:48
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.31 kb
#include <bits/stdc++.h>
#define maxN 100005
#define maxLog 25
using namespace std;
vector<int> v[maxN];
int cnt,n,m,i,j,x,y,lg[2*maxN],pos[maxN];
int lvl[2*maxN],euler[2*maxN],rmq[maxLog][2*maxN];
void dfs(int nod,int dep)
{
    vector<int>::iterator it;
    euler[++cnt]=nod;
    lvl[cnt]=dep;
    pos[nod]=cnt;
    for(it=v[nod].begin();it!=v[nod].end();it++)
    {
        dfs(*it,dep+1);
        euler[++cnt]=nod;
        lvl[cnt]=dep;
    }
}
void query(int x,int y)
{
    int poz;
    if(x>y) swap(x,y);
    int len=lg[y-x+1];
    poz=rmq[len][x];
    if(lvl[poz]>lvl[rmq[len][y+1-(1<<len)]])
        poz=rmq[len][y+1-(1<<len)];
    printf("%d\n",euler[poz]);
}
int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    scanf("%d %d",&n,&m);
    for(i=2;i<=n;i++)
        scanf("%d",&x),
        v[x].push_back(i);
    dfs(1,0);
    for(i=2;i<=cnt;i++)
        lg[i]=lg[i/2]+1;
    for(i=1;i<=cnt;i++)
        rmq[0][i]=i;
    for(i=1;(1<<i)<=cnt;i++)
        for(j=1;j+(1<<(i-1))<=cnt+1;j++)
        {
            rmq[i][j]=rmq[i-1][j];
            if(lvl[rmq[i][j]]>lvl[rmq[i-1][j+(1<<(i-1))]])
                rmq[i][j]=rmq[i-1][j+(1<<(i-1))];
        }
    for(i=1;i<=m;i++)
        scanf("%d %d",&x,&y),
        query(pos[x],pos[y]);
    return 0;
}