Cod sursa(job #2121249)

Utilizator valorosu_300Cristian Gherman valorosu_300 Data 3 februarie 2018 14:54:20
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.39 kb
#include <fstream>
#include <vector>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
const int N = 100002, L = 19;
int poz[N], lev[N], lg[2*N], put[L], rmq[L][2*N], cnt, x, y;
vector <int> v[N];
void DFS(int ns){
    int sz = v[ns].size();
    rmq[0][++cnt] = ns;
    poz[ns] = cnt;
    for(int i=0;i<sz;i++){
        lev[v[ns][i]] = lev[ns] + 1;
        DFS(v[ns][i]);
        rmq[0][++cnt] = ns;
    }
}
void process(){
    for(int i=2;i<=cnt;i++)
        lg[i] = lg[i/2] + 1;
    put[0] = 1;
    for(int i=1;i<L;i++)
        put[i] = put[i-1] * 2;
    for(int i=1;put[i]<=cnt;i++)
        for(int j=1;j<=cnt-put[i]+1;j++){
            rmq[i][j] = rmq[i-1][j];
            if(lev[rmq[i-1][j+put[i-1]]] < lev[rmq[i][j]])
                rmq[i][j] = rmq[i-1][j+put[i-1]];
        }
}
int lca(){
    int len, log, dist, sol;
    x = poz[x];
    y = poz[y];
    if(x > y)
        swap(x,y);
    len = y - x + 1;
    log = lg[len];
    dist = len - put[log];
    sol = rmq[log][x];
    if(lev[sol] > lev[rmq[log][x+dist]])
        sol = rmq[log][x+dist];
    return sol;
}
int main()
{
    int n,m;
    in>>n>>m;
    for(int i=2;i<=n;i++){
        in>>x;
        v[x].push_back(i);
    }
    DFS(1);
    process();
    for(int i=1;i<=m;i++){
        in>>x>>y;
        out<<lca()<<"\n";
    }
    in.close();
    out.close();
    return 0;
}