Cod sursa(job #1098235)

Utilizator teoionescuIonescu Teodor teoionescu Data 4 februarie 2014 17:48:24
Problema Lowest Common Ancestor Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 2.68 kb
#include<fstream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<string>
#include<queue>
#define abs(x) ((x>0)?(x):(-(x)))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define ll long long
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
const int Nmax = 100005;
int T,N,K;
vector<int> G[Nmax];
int mark[Nmax],L[Nmax],E[2*Nmax];
int First[Nmax],Last[Nmax];
int rmq[18][2*Nmax],lg[2*Nmax];
int broken[Nmax];
struct LCA{
    int x,y,l;
} Lca[Nmax];
inline bool cmp(LCA a,LCA b){
    return a.l>b.l;
}
void Dfs(int x,int depth){
    mark[x]=1;
    E[++E[0]]=x;First[x]=E[0];
    L[x]=depth;
    for(vector<int>::iterator it=G[x].begin();it!=G[x].end();++it){
        if(!mark[*it]){
            Dfs(*it,depth+1);
            E[++E[0]]=x;
        }
    }
    Last[x]=E[0];
}
void BuildRMQ(){
    for(int i=2;i<=E[0];i++){
        lg[i]=lg[i>>1]+1;
    }
    for(int i=1;i<=E[0];i++){
        rmq[0][i]=E[i];
    }
    for(int i=1;(1<<i)<=E[0];i++){
        for(int j=1;j+(1<<i)-1<=E[0];j++){
            rmq[i][j]=rmq[i-1][j];
            if( L[ rmq[i-1][j+(1<<(i-1))] ] < L[ rmq[i][j] ] ) rmq[i][j] = rmq[i-1][j+(1<<(i-1))] ;
        }
    }
}
int RMQ(int a,int b){
    a=First[a];
    b=First[b];
    if(a>b) swap(a,b);
    int dist=b-a;
    int log=lg[dist];
    int lca=rmq[log][a];
    if( L[ rmq[log][a+dist-(1<<log)+1] ] < L[lca]  ) lca=rmq[log][a+dist-(1<<log)+1];
    return lca;
}
void Reset(){
    E[0]=0;
    memset(mark,0,sizeof(mark));
    memset(broken,0,sizeof(broken));
    for(int i=1;i<=N;i++) G[i].clear();
}
int main(){
    //in>>T;
    T=1;
    for(;T;--T){
        in>>N>>K;
        Reset();
        /*
        for(int i=1;i<N;i++){
            int x,y;
            in>>x>>y;
            G[x].push_back(y);
            G[y].push_back(x);
        }
        */
        for(int i=1;i<N;i++){
            int x;
            in>>x;
            G[i+1].push_back(x);
            G[x].push_back(i+1);
        }
        Dfs(1,1);
        BuildRMQ();
        for(int i=1;i<=K;i++){
            int x,y;
            in>>x>>y;
            if(x>y) swap(x,y);
            Lca[i].x=x;
            Lca[i].y=y;
            Lca[i].l=RMQ(x,y);
            out<<Lca[i].l<<'\n';
        }
        /*
        sort(Lca+1,Lca+K+1,cmp);
        int Ans=0;
        for(int i=1;i<=K;i++){
            if(!broken[ Lca[i].l ] && !broken[ Lca[i].x ] && !broken[ Lca[i].y ]){
                Ans++;
                for(int j=First[ Lca[i].l ];j<=Last[ Lca[i].l ];j++){
                    broken[j]=1;
                }
            }
        }
        */
    }
    return 0;
}