Cod sursa(job #1747205)

Utilizator VladTiberiuMihailescu Vlad Tiberiu VladTiberiu Data 24 august 2016 16:51:19
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.71 kb
#include <bits/stdc++.h>

#define NMax 200002
using namespace std;
ifstream f("lca.in");
ofstream g("lca.out");

int n,m,x,nr,y;
int euler[NMax],val[NMax],viz[NMax],ind[NMax],lg[NMax];
int rmq[20][NMax],sol[20][NMax];
vector<int> G[NMax];

void dfs(int nod, int tata){
    viz[nod] = viz[tata] + 1;
    euler[++nr] = nod;
    val[nr] = viz[nod];
    ind[nod] = nr;

    for(int i = 0; i < G[nod].size(); ++i){
        if(!viz[G[nod][i]]){
            dfs(G[nod][i],nod);
            euler[++nr] = nod;
            val[nr] = viz[nod];
        }
    }
}
int RMQ(int x,int y){
    int diff = lg[y - x + 1];
    if(rmq[diff][x] < rmq[diff][y - (1 << diff) + 1]){
        return sol[diff][x];
    }else{
        return sol[diff][y - (1 << diff) + 1];
    }
}
int main()
{
    f >> n >> m;
 //   g << 1.0*(sizeof(sol) + sizeof(rmq))/1024/1024;
    for(int i = 1; i < n; ++i){
        f >> x;
        G[x].push_back(i + 1);
        G[i + 1].push_back(x);
    }
    dfs(1,0);
    for(int i = 1; i <= nr; ++i){
        rmq[0][i] = val[i];
        sol[0][i] = euler[i];
    }
    lg[1] = 0;
    for(int i = 2; i <= nr; ++i){
        lg[i] = lg[i/2] + 1;
    }
    for(int i = 1; (1<<i) <= nr; ++i){
        for(int j = 1; j <= nr - (1 << i) + 1; ++j){
            if(rmq[i - 1][j] < rmq[i - 1][j + (1 << (i - 1))]){
                rmq[i][j] = rmq[i - 1][j];
                sol[i][j] = sol[i - 1][j];
            }else{
                rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))];
                sol[i][j] = sol[i - 1][j + (1 << (i - 1))];
            }
        }
    }
    for(int i = 1; i <= m; ++i){
        f >> x >> y;
        g << RMQ(ind[x],ind[y]) << '\n';
    }
    return 0;
}