Cod sursa(job #2374373)

Utilizator Teo_1101Mititelu Teodor Teo_1101 Data 7 martie 2019 18:14:19
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.85 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

const int NMAX = 200002;
int N,Q;
int T[NMAX];
int lg[NMAX];

int PE[2*NMAX],Grad[2*NMAX];
int n;

vector <int> Ad[NMAX];

pair <int, int>  rmq[20][2*NMAX];

int poz[2*NMAX];

int x,y;

void DFS(int nod,int grad)
{
    PE[++n]=nod;
    Grad[n]=grad;
    for(int i=0;i<Ad[nod].size();++i)
    {
        int w = Ad[nod][i];
        DFS(w,grad+1);
        PE[++n]=nod;
        Grad[n]=grad;
    }
}
void Read()
{
    fin>>N>>Q;
    for(int i=2;i<=N;++i)
        {
            fin>>T[i];
            Ad[T[i]].push_back(i);
        }
}

void LCA()
{
    DFS(1,1);

    //for(int i=1;i<=n;++i)fout<<PE[i]<<" ";
    for(int i=1;i<=n;++i)
        {
            rmq[0][i].first=Grad[i];
            rmq[0][i].second=PE[i];
            if(!poz[PE[i]])poz[PE[i]]=i;
        }
    //for(int i=1;i<=N;++i)fout<<poz[i]<<' ';
    for(int i=1; ( 1 << i) <= n; ++i)
        for(int j=1 ; j + ( 1 <<  i  ) -1 <= n ; ++j )
    {

        if(rmq[i-1][j].first < rmq[i-1][j + ( 1 << (i-1) ) ].first)
        {
            rmq[i][j]=rmq[i-1][j];
        }
        else rmq[i][j]=rmq[i-1][j + ( 1 << (i-1) ) ];
    }

    lg[2]=1;
    for(int i=3;i<=NMAX-2;++i)
        lg[i]=lg[i/2]+1;

    for(int q=1;q<=Q;++q)
    {
        fin>>x>>y;

        //fout<<x<<" "<<y<<"\n";

        x=poz[x];
        y=poz[y];

        if(x>y)swap(x,y);


        int L=(y-x)+1;
        //fout<< min( rmq[lg[L]][x] , rmq[lg[L]][ y - ( 1 << lg[L]) + 1 ]) << "\n";
        if( rmq[lg[L]][x].first < rmq[lg[L]][ y - ( 1 << lg[L]) + 1 ].first )
            fout<<rmq[lg[L]][x].second<<"\n";
        else fout<<rmq[lg[L]][y-(1<<lg[L])+1].second<<"\n";
    }
}
int main()
{
    Read();
    LCA();
    return 0;
}