Cod sursa(job #2416913)

Utilizator Daria09Florea Daria Daria09 Data 28 aprilie 2019 16:02:47
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.69 kb
#include <bits/stdc++.h>
#define dim 2*100005
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");
vector <int> sons[dim];
int n,m,crt;
int lvl[dim],euler[dim],first[dim],logg[dim],rmq[20][dim];
void Read()
{
    f>>n>>m;
    for(int i=1; i<n; ++i)
    {
        int x;
        f>>x;
        sons[x].push_back(i+1);
    }
}
void Dfs(int node=1,int niv=0)
{
    lvl[node]=niv;
    euler[++crt]=node;
    if(!first[node])first[node]=crt;
    for(int i=0; i<sons[node].size(); ++i)
    {
        Dfs(sons[node][i],niv+1);
        euler[++crt]=node;
    }
}
void BuildRmq()
{
    n*=2;
    for(int i=2; i<=n; ++i)
        logg[i]=1+logg[i/2];
    for(int i=1; i<n; ++i)
        rmq[0][i]=i;
    for(int i=1; i<=logg[n]; ++i)
        for(int j=1; j<n; ++j)
            if(j+(1<<i)>=n)
                rmq[i][j]=rmq[i-1][j];
            else
            {
                int node1,node2;
                node1=rmq[i-1][j];
                node2=rmq[i-1][j+(1<<(i-1))];
                if(lvl[euler[node1]]<lvl[euler[node2]])
                    rmq[i][j]=node1;
                else
                    rmq[i][j]=node2;
            }
}
int Query(int x,int y)
{
    if(first[x]>first[y])
        swap(x,y);
    x=first[x];
    y=first[y];
    int node1,node2;
    node1=rmq[logg[y-x+1]][x];
    node2=rmq[logg[y-x+1]][x+y-x+1-(1<<logg[y-x+1])];
    if(lvl[euler[node1]]<lvl[euler[node2]])
        return euler[node1];
    return euler[node2];
}
void Solve()
{
    for(int i=1; i<=m; ++i)
    {
        int x,y;
        f>>x>>y;
        g<<Query(x,y)<<'\n';
    }
}
int main()
{
    Read();
    Dfs();
    BuildRmq();
    Solve();
    return 0;
}