Cod sursa(job #2082062)

Utilizator ScarymovieMocanu Alexandru Scarymovie Data 5 decembrie 2017 17:50:26
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.49 kb
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
vector<int> first,pe,nivel;
vector<vector<int> >la;
int RMQ[200005][20];
void dfs(int nod)
{
    first[nod]=pe.size();
    pe.push_back(nod);unsigned int i;
    for(i=0;i<la[nod].size();++i)
        {
            nivel[la[nod][i]]=nivel[nod]+1;
            dfs(la[nod][i]);
            pe.push_back(nod);
        }
}
void ConstruiesteRMQ()
{
    unsigned int putere=2,exp=1;unsigned int i;
    for(i=0;i<pe.size();++i) RMQ[i][0]=pe[i];
    while(putere<=pe.size())
    {
        for(i=0;i+putere-1<pe.size();++i)
            if(nivel[RMQ[i][exp-1]]<nivel[RMQ[i+putere/2][exp-1]])
                RMQ[i][exp]=RMQ[i][exp-1];
            else RMQ[i][exp]=RMQ[i+putere/2][exp-1];
        putere<<=1;exp++;
    }
}
int rmq(int st,int dr)
{
    if(st>dr) st^=dr^=st^=dr;
    int lungime=dr-st+1;
    int lg=1,exp=0;
    while(lg<=lungime) lg<<=1,++exp;
    lg>>=1,--exp;
    if(nivel[RMQ[st][exp]]<nivel[RMQ[st+lungime-lg][exp]])
        return RMQ[st][exp];
    return RMQ[st+lungime-lg][exp];
}
int main()
{
    ifstream f("lca.in");
    ofstream g("lca.out");
    int n,m,i,x,y;
    f>>n>>m;la.resize(n);nivel.resize(n);
    for(i=1;i<n;++i) {f>>x;la[x-1].push_back(i);}
    first.resize(n);
    dfs(0);
    la.clear();
    ConstruiesteRMQ();
    for(i=0;i<m;++i)
        {
            f>>x>>y;x--;y--;
            int result=rmq(first[x],first[y])+1;
            g<<result<<'\n';
        }
    return 0;
}