Cod sursa(job #2874045)

Utilizator popescuadrianpopescuadrian popescuadrian Data 19 martie 2022 12:39:05
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.96 kb
#include <fstream>
#include <vector>

using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
int poz[200005];
int depth[200005];
int euler[200005];
vector<int>adj[100005];
int numar=0;
void dfs(int curr)
{
    int i,k;
    numar++;
    poz[curr]=numar;
    euler[numar]=curr;
    for(i=0;i<adj[curr].size();i++)
    {
        k=adj[curr][i];
        depth[k]=depth[curr]+1;
        dfs(k);
        numar++;
        euler[numar]=curr;
    }
}
pair<int,int> rmq[30][200005];
int main()
{
    int n,q,i,a,b,poz1,poz2,dist,logus,j;
    cin>>n>>q;
    for(i=2;i<=n;i++)
    {
        cin>>a;
        adj[a].push_back(i);
    }
    int nolog=1;
    depth[1]=1;
    dfs(1);
    for(i=1;i<=numar;i++)
    {
        rmq[0][i].first=depth[euler[i]];
        rmq[0][i].second=euler[i];
    }
    for(i=1;i<=20;i++)
    {
        rmq[i][numar].first=rmq[i-1][numar].first;
        rmq[i][numar].second=rmq[i-1][numar].second;
    }
    for(i=1;i<=20;i++)
    {
        for(j=1;j<=numar;j++)
        {
            if(rmq[i-1][j].first<=rmq[i-1][min(numar,j+nolog)].first)
            {
                rmq[i][j].first=rmq[i-1][j].first;
                rmq[i][j].second=rmq[i-1][j].second;
            }
            else
            {
                rmq[i][j].first=rmq[i-1][min(numar,j+nolog)].first;
                rmq[i][j].second=rmq[i-1][min(numar,j+nolog)].second;
            }
        }
        nolog=nolog*2;
    }
    for(i=1;i<=q;i++)
    {
        cin>>a>>b;
        poz1=poz[a];
        poz2=poz[b];
        if(poz2<poz1)
        {
            swap(poz1,poz2);
        }
        dist=poz2-poz1;
        logus=31-__builtin_clz(dist);
        if(rmq[logus][poz1].first<rmq[logus][poz2-(1<<logus)+1].first)
        {
            cout<<rmq[logus][poz1].second;
        }
        else
        {
            cout<<rmq[logus][poz2-(1<<logus)+1].second;
        }
        cout<<'\n';

    }
    return 0;
}