Cod sursa(job #2603455)

Utilizator BogdanRuleaBogdan Rulea BogdanRulea Data 19 aprilie 2020 21:34:49
Problema Lowest Common Ancestor Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.47 kb
#include <fstream>
#include <vector>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
const int NMAX=100005;
vector <int> g[NMAX];

int k,lg[NMAX<<1],H[NMAX << 1],l[NMAX << 1],rmq[20][NMAX<<2],First[NMAX],n,m;
void citire()
{
    cin>>n>>m;
    for(int i=2; i<=n; i++)
    {
        int x;
        cin>>x;
        g[x].push_back(i);

    }
}

void dfs(int nod,int lev)
{
    H[++k]=nod;
    l[k]=lev;
    First[nod]=k;
    for(vector <int> :: iterator it=g[nod].begin(); it!=g[nod].end(); it++)
    {
        dfs(*it,lev+1);
        H[++k]=nod;
        l[k]=lev;
    }
}
void RMQ()
{
    for(int i=2; i<=k; ++i)
        lg[i]=lg[i>>1]+1;
    for(int i=1; i<=k; ++i)
        rmq[0][i]=i;
    for(int i=1; (1<<i)<k; ++i)
        for(int j=1; j<=k-(1<<i); ++j)
        {
            int L=1<<(i-1);
            rmq[i][j]=rmq[i-1][j];
            if(l[rmq[i-1][j+L]]<l[rmq[i][j]])
            {
                rmq[i][j]=rmq[i-1][j+L];
            }
        }

}
int lca(int x,int y)
{
    int diferenta,L,sol,sh;
    int a=First[x],b=First[y];
    if(a>b)
        swap(a,b);
    diferenta=b-a+1;
    L=lg[diferenta];
    sol=rmq[L][a];
    sh=diferenta-(1<<L);
    if(l[sol]>l[rmq[L][a+sh]])
        sol=rmq[L][a+sh];
    return H[sol];
}
int main()
{
    citire();
    dfs(1,0);
    RMQ();
    for(int i=1; i<=m; i++)
    {
        int x,y;
        cin>>x>>y;
        cout<<lca(x,y)<<endl;
    }
    return 0;
}