Cod sursa(job #1537869)

Utilizator gbibBacotiu Gabi gbib Data 28 noiembrie 2015 11:24:00
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.56 kb
#include <bits/stdc++.h>

using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
vector <int> v[100005];
int cnt;
int euler[200005],lev[100005],fir[100005],lg[200005];
struct jiji{int nod,cost;} rmq[18][200005];
void dfs(int x)
{
    int i;
    euler[++cnt]=x;
    fir[x]=cnt;
    for(i=0;i<v[x].size();i++)
    {
        lev[v[x][i]]=lev[x]+1;
        dfs(v[x][i]);
        euler[++cnt]=x;
    }
}
int lca(int x,int y)
{
    x=fir[x];
    y=fir[y];
    if(x>y)
        swap(x,y);

    int dif=y-x+1;
    int p=lg[dif];
    if(rmq[p][x].cost<=rmq[p][y-(1<<p)+1].cost)
    {
        return rmq[p][x].nod;
    }
    else
    {
        return rmq[p][y-(1<<p)+1].nod;
    }
}
int main()
{int i,j;
int n,m;
in>>n>>m;
for(i=2;i<=n;i++)
{
    in>>j;
    v[j].push_back(i);
}
lev[1]=0;
dfs(1);


    lg[1]=0;
    for(i=2;i<=cnt;i++)
        lg[i]=lg[i/2]+1;
    for(i=1;i<=cnt;i++)
    {
        rmq[0][i].cost=lev[euler[i]];
        rmq[0][i].nod=euler[i];
    }
    for(i=1;(1<<i)<=cnt;i++)
    {
        for(j=1;j+(1<<i)-1<=cnt;j++)
        {
            if(rmq[i-1][j].cost<=rmq[i-1][j+(1<<(i-1))].cost)
            {
                rmq[i][j].cost=rmq[i-1][j].cost;
                rmq[i][j].nod= rmq[i-1][j].nod;
            }
            else
            {
                rmq[i][j].cost=rmq[i-1][j+(1<<(i-1))].cost;
                rmq[i][j].nod=rmq [i-1][j+(1<<(i-1))].nod;
            }
        }
    }
for(i=1;i<=m;i++)
{
    int x,y;
    in>>x>>y;
    out<<lca(x,y)<<'\n';
}
    return 0;
}