Cod sursa(job #1061376)

Utilizator mazaandreiAndrei Mazareanu mazaandrei Data 19 decembrie 2013 17:39:43
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.97 kb
#include<fstream>
#include<vector>
using namespace std;
ifstream in("lca.in"); ofstream out("lca.out");
int t[100005],n,nr;
int p[200010], niv[200010];
int poz[100005],m,a1,b1,A,B,ans,rasp;
int a[1600010];
vector <int> l[100005];
void dfs(int nod, int lev){
    niv[nod]=lev;
    p[++nr] =nod;
    if(poz[nod]==0) poz[nod]=nr;
    for(vector <int> :: iterator it=l[nod].begin();it!=l[nod].end();++it)
        if(poz[(*it)]==0 && (*it)!=1){
            dfs((*it),lev+1);
            //niv[++nr]=lev;
            p[++nr]=nod;
        }
}// In vectorul p am parcurgerea euleriana a grafului, iar in niv am nivelele fiecarui nod
void query(int nod, int st, int dr){
    if(A<=st && dr<=B){
        if(ans>niv[a[nod]]){
            ans =niv[a[nod]];
            rasp=a[nod];
        }
    }//Caut minimul pe intervalul a-b dpdv al nivelului. In arbore tin nodurile grafului, aranjate dupa nivelul lor
    else{
        int m=(st+dr)/2;
        if(A<=m) query(nod*2,st,m);
        if(m<B)  query(nod*2+1,m+1,dr);
    }
}
void update(int nod, int st, int dr, int poz, int val){
    if(st==dr)
        a[nod]=val;
    else{
        int m=(st+dr)/2;
        if(m>=poz) update(nod*2,st,m,poz,val);
        else       update(nod*2+1,m+1,dr,poz,val);
       // a[nod]=min(a[nod*2],a[nod*2+1]);
       if(niv[a[nod*2]]>niv[a[nod*2+1]]) a[nod]=a[nod*2+1];
       else                              a[nod]=a[nod*2];
    }
}
int main(){
    in>>n>>m;
    for(int i=2;i<=n;++i){
        in>>t[i];
        l[t[i]].push_back(i);
    }
    dfs(1,0);
    niv[0]=9999999;
    for(int i=1;i<=nr;++i)
        update(1,1,nr,i,p[i]);
    for(;m;--m){
        in>>a1>>b1; //A si B sunt primele pozitii ale nodurilor cautate in parcurgerea euleriana. Nodul cautat va fi
        A=min(poz[a1],poz[b1]); B=max(poz[a1],poz[b1]); //nodul de nivel minim dintre A si B
        ans=9999999,rasp=0;
        query(1,1,nr);
        out<<rasp<<'\n';
    }
    out.close();
    return 0;
}