Cod sursa(job #2653209)

Utilizator gavra_bogdanBogdan Gavra gavra_bogdan Data 27 septembrie 2020 12:56:05
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.25 kb
#include <iostream>
#include <vector>
#include <fstream>

const int nmax = 2e5 + 5;

std::vector<int>l[nmax];
int rmq[nmax][30], h[nmax];

void dfs(int nod){
    h[nod] = h[rmq[nod][0]] + 1;
    for(auto x:l[nod])
            dfs(x);
}

int kth_ancestor(int nod, int k){
    for(int i=0;i<=19;i++) if((1<<i)&k) nod = rmq[nod][i];
    return nod;
}

int lca(int a, int b){
    if(h[a]>h[b]) std::swap(a, b);
    b = kth_ancestor(b, h[b]-h[a]);
    if(a==b) return a;
    int ans = -1, lvl = 19;
    while(lvl--){
        int ka = kth_ancestor(a, (1<<lvl)), kb = kth_ancestor(b, (1<<lvl));
        if(ka==kb) ans = ka;
        else a = ka, b = kb;
    }
    return ans;
}

bool ison(int nod, int a, int b){
    int x = lca(a, b);
    return ((lca(nod, a) == nod or lca(nod, b) == nod) and lca(x, nod)==x);
}

int main(){
    std::ifstream in("lca.in");
    std::ofstream out("lca.out");
    int n, q, a, b, c, d, u, v;
    in>>n>>q;
    for(int i=1;i<n;i++){
        in>>rmq[i+1][0];
        l[rmq[i+1][0]].push_back(i+1);
    }
    dfs(1);
    for(int i = 1; i <= n; i++)
        for(int j = 1; j < 20; j++)
            rmq[i][j]=rmq[rmq[i][j-1]][j-1];
    while(q--){
        in>>u>>v;
        out<<lca(u, v)<<"\n";
    }
}