Cod sursa(job #1210479)

Utilizator buzu.tudor67Tudor Buzu buzu.tudor67 Data 20 iulie 2014 00:58:42
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.69 kb
#include<fstream>
#include<vector>
using namespace std;
ifstream fi("lca.in");
ofstream fo("lca.out");

const int max_n = 100005;

vector <int> a[max_n];
int FIRST[max_n],NODE[2*max_n],LEVEL[2*max_n],nr;
int rmq[2*max_n][19],lg[2*max_n];
int i,n,m,x,y;

void swap(int &a, int &b){
     int aux;
     aux=a; a=b; b=aux;
}

void dfs(int k, int nod){
     nr++;
     NODE[nr]=nod;
     LEVEL[nr]=k;
     if(!FIRST[nod]) FIRST[nod]=nr;
     
     for(unsigned int j=0;j<a[nod].size();j++)
        {
         dfs(k+1,a[nod][j]);
         nr++;
         NODE[nr]=nod;
         LEVEL[nr]=k;
        }
}

void logaritm_n(int n, int lg[max_n]){
     int i; lg[1]=0;
     for(i=2;i<=n;i++) lg[i]=lg[i/2]+1;
}

void r_m_q(int a[2*max_n], int n, int rmq[2*max_n][19]){
     int i,j,lim;
     
     lim=lg[n];
     for(i=1;i<=n;i++) rmq[i][0]=i;
     
     for(j=1; j<=lim; j++)
       for(i=1; i+(1<<j)-1<=n; i++)
         if(a[rmq[i][j-1]]<a[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 lca(int x, int y){
    int a=FIRST[x],b=FIRST[y];
    if(a>b) swap(a,b);
    
    int lung=b-a+1;
    int z=lg[lung];
    if(LEVEL[rmq[a][z]]<LEVEL[rmq[b-(1<<z)+1][z]]) return NODE[rmq[a][z]];
    else return NODE[rmq[b-(1<<z)+1][z]];
}

void queries(int m){
     int x,y;
     for(;m>0;m--){
                   fi>>x>>y;
                   fo<<lca(x,y)<<"\n";
                  }
}

int main(){
    fi>>n>>m;
    for(i=2;i<=n;i++){ fi>>x; a[x].push_back(i); }
    
    dfs(0,1);
    
    logaritm_n(nr,lg);
    
    r_m_q(LEVEL,nr,rmq);
    
    queries(m);
    
    fi.close();
    fo.close();
    return 0;
}