Cod sursa(job #2393147)

Utilizator smoc_georgemarianSmoc George-Marian smoc_georgemarian Data 30 martie 2019 22:00:55
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.83 kb

#include <bits/stdc++.h>
#define DMAX 100010
#define LMAX 20

using namespace std;

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

vector <int> V[DMAX];

int M[2*DMAX][LMAX];
int ind[DMAX];
int euler[2*DMAX];
int h[DMAX];
int level[2*DMAX];
bool uz[DMAX];

int n,m,cate;

void citire();
void dfs(int node);
void constr();

int main(){
    int i,x,y,aux,k;
    citire();
    dfs(1);
    constr();

    for(i=1;i<=m;i++)
        {fin>>x>>y;
         x=ind[x];
         y=ind[y];
         if(x<y)
            {aux=y;
             y=x;
             x=aux;
            }

         k=log2(x-y+1);
         if(level[M[y][k]] < level[M[x-(1<<k)+1][k]])
            fout<<euler[M[y][k]]<<'\n';
            else
            fout<<euler[M[x-(1<<k)+1][k]]<<'\n';
        }
    return 0;
}
void citire(){
    int i,tata;
    fin>>n>>m;
    for(i=2;i<=n;i++)
        {fin>>tata;
         V[tata].push_back(i);
         V[i].push_back(tata);
        }
}
void dfs(int node){
    int i;

    cate++;
    euler[cate]=node;
    level[cate]=h[node];

    uz[node]=true;

    if(!ind[node])
       ind[node]=cate;

    for(i=0;i<V[node].size();i++)
        if(!uz[V[node][i]])
           {h[V[node][i]]=h[node]+1;
            dfs(V[node][i]);

            cate++;
            euler[cate]=node;
            level[cate]=h[node];
           }
}
void constr(){
    int i,j;
    for(i=1;i<=2*n-1;i++)
        M[i][0]=i;
    for(j=1; (1<<j)<=2*n-1; j++)
        for(i=1;i+(1<<j)-1<=2*n-1;i++)
            if(level[M[i][j-1]] < level[M[i+(1<<(j-1))][j-1]])
                M[i][j]=M[i][j-1];
                else
                M[i][j]=M[i+(1<<(j-1))][j-1];
}
///LCA(u,v)=Euler[RMQ(index(u),index(v))];
///Euler - nodul care apare din parcurgere pe rand
///Index - prima aparitie a nodului in euler