Cod sursa(job #2641113)

Utilizator PatrickCplusplusPatrick Kristian Ondreovici PatrickCplusplus Data 10 august 2020 10:31:37
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.5 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int const nmax = 200005;
int n, m, z, ap[nmax * 3], r[20][nmax * 3], lg[nmax * 3];
pair <int, int> v[nmax * 3];
vector <int> G[nmax];
void Read(){
    fin >> n >> m;
    for (int i = 2; i <= n; ++i){
        int parinte;
        fin >> parinte;
        G[parinte].push_back(i);
    }
}
void Dfs(int nod, int nivel){
    v[++z] = {nod, nivel};
    ap[nod] = z;
    for (auto vecin : G[nod]){
        Dfs(vecin, nivel + 1);
        v[++z] = {nod, nivel};
        r[0][z] = z;
    }
}
void Rmq(){
    for (int i = 2; i <= z; ++i) lg[i] = 1 + lg[i / 2];
    for (int i = 1; i <= z; ++i) r[0][i] = i;
    for (int j = 1; (1 << j) < z; ++j){
        for (int i = 1; i <= z - (1 << j); ++i){
            r[j][i] = r[j - 1][i];
            if (v[r[j - 1][i + (1 << (j - 1))]].second < v[r[j][i]].second){
                r[j][i] = r[j - 1][i + (1 << (j - 1))];
            }
        }
    }
}
int lca(int x, int y){
    int diff, l, sol, sh;
	int a = ap[x], b = ap[y];
	if(a > b) swap(a, b);
	diff = b - a + 1;
	l = lg[diff];
	sol = r[l][a];
	sh = diff - (1 << l);
	if(v[sol].second > v[r[l][a + sh]].second)
		sol = r[l][a + sh];
	return v[sol].first;

}
void Solve(){
    while (m--){
        int x, y;
        fin >> x >> y;
        fout << lca(x, y) << "\n";
    }
}
int main(){
    Read();
    Dfs(1, 0);
    Rmq();
    Solve();
    fin.close();
    fout.close();
    return 0;
}