Cod sursa(job #3231281)

Utilizator MegaCoderMinoiu Teodor Mihai MegaCoder Data 25 mai 2024 15:57:24
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.41 kb
#include<fstream>
#include<vector>
std::ifstream fin("lca.in");
std::ofstream fout("lca.out");
const int NMAX=100001;
int e[2*NMAX-1], l[2*NMAX-1], h[NMAX];
int rmq[2*NMAX-1][20];
int lg[2*NMAX-1];
std::vector<int>g[NMAX];
int n, q;
void read()
{
    fin>>n>>q;
    for(int i=1; i<n; ++i)
    {
        int node;
        fin>>node;
        g[node].push_back(i+1);
    }
}
int k=1;
void euler(int node, int depth)
{
    e[k]=node;
    if(!h[node])
        h[node]=k;
    l[k++]=depth;
    for(auto &it:g[node])
    {
        euler(it, depth+1);
        e[k]=node;
        l[k++]=depth;
    }
}
void precalc()
{
    lg[1]=0;
    for(int i=2; i<2*NMAX-1; ++i)
        lg[i]=lg[i/2]+1;

    for(int i=1; i<=2*n-1; ++i)
        rmq[i][0]=i;

    for(int i=1; (1<<i)<=2*n-1; ++i)
        for(int j=1; j<=(2*n-1)-(1<<i)+1; ++j)
        {
            int val=(1<<(i-1));
            int a=l[rmq[j][i-1]];
            int b=l[rmq[j+val][i-1]];
            if(a<b)
                rmq[j][i]=rmq[j][i-1];
            else
                rmq[j][i]=rmq[j+val][i-1];
        }
}
void solve()
{
    for(int i=0; i<q; ++i)
    {
        int u, v;
        fin>>u>>v;
        if(h[v]<h[u])
            std::swap(u, v);
        int dist=h[v]-h[u]+1;
        int aux=lg[dist], rem=dist-(1<<aux);
        fout<<std::min(e[rmq[h[u]][aux]], e[rmq[h[u]+rem][aux]])<<'\n';
    }
}
int main()
{
    read();
    euler(1, 0);
    precalc();
    solve();
    return 0;
}