Cod sursa(job #3244020)

Utilizator BogdanBurescuBogdan Burescu BogdanBurescu Data 22 septembrie 2024 23:47:37
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.33 kb
#include <fstream>
#include <vector>
#include <cmath>

using namespace std;

ifstream cin ("lca.in");
ofstream cout ("lca.out");

int t,n,m,i,k,j,a[200005],nivel[200005],euler[200005],val[200005],rmq[200005][20],x,y,ok,d,q,l,r,mij,sum,nr,maxnr,minnr,maxp,minp;
vector<int>g[200005];

void parcurgere(int nod, int niv)
{
    k++;
    euler[k]=nod;
    nivel[k]=niv;
    val[nod]=k;
    for(auto it:g[nod])
    {
        parcurgere(it, niv+1);
        k++;
        euler[k]=nod;
        nivel[k]=niv;
    }
}

void frmq()
{
    for(int i=0;i<=k;i++)
        rmq[i][0]=i;
    for(int j=1; (1<<j)<=k; j++)
        for(int i=0; i+(1<<j)-1<k; i++)
            if(nivel[rmq[i][j-1]]<nivel[rmq[i+(1<<(j-1))][j-1]])
                rmq[i][j]=rmq[i][j-1];
            else
                rmq[i][j]=rmq[i+(1<<(j-1))][j-1];
}

int query(int x, int y)
{
    int q=log2(y-x+1);
    if(nivel[rmq[x][q]]<nivel[rmq[y-(1<<q)+1][q]])
        return rmq[x][q];
    return rmq[y-(1<<q)+1][q];
}

int main()
{
    cin>>n>>m;
    for(i=2;i<=n;i++)
    {
        cin>>x;
        g[x].push_back(i);
    }
    k=-1;
    parcurgere(1,0);
    frmq();
    for(j=1;j<=m;j++)
    {
        cin>>x>>y;
        if(val[x]>val[y])
            swap(x,y);
        cout<<euler[query(val[x],val[y])]<<endl;
    }
    return 0;
}