Cod sursa(job #2601704)

Utilizator k2e0e0w3qDumitrescu Gheorghe k2e0e0w3q Data 14 aprilie 2020 23:56:28
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.56 kb
#include <bits/stdc++.h>
#define N 100000
#define _log(x) 31-__builtin_clz(x)
using namespace std;

bitset <N+1> seen;
vector <int> G[N+1], euler, level;
int t[N+1], first[N+1], niv[N+1], seg[_log(N)+1][N];
void go (int x) {
    euler.push_back(x);
    level.push_back(niv[x]);
    seen[x]=1;
    for (auto it: G[x])
        if (!seen[it]) {
            first[it]=euler.size();
            go(it);
        }
    euler.push_back(t[x]);
    level.push_back(niv[t[x]]);
}

void rmq () {
    int i, j, n=euler.size();;
    for (i=0; i<n; ++i)
        seg[0][i]=i;
    for (i=1; (1<<i)<n; i++)
        for (j=0; j+(1<<i)<=n; j++) {
            int can1=seg[i-1][j],
                can2=seg[i-1][j+(1<<i-1)];
            if (level[can1]<level[can2])
                seg[i][j]=can1;
            else
                seg[i][j]=can2;
        }
}

int main () {
    ifstream fin("lca.in");
    ofstream fout("lca.out");
    ios::sync_with_stdio(false);

    int m, i, q, x, y;
    fin >> n >> q;
    for (i=2; i<=n; i++) {
        fin >> x;
        t[i]=x;
        niv[i]=niv[x]+1;
        G[x].push_back(i);
    }

    first[1]=euler.size();
    go(1);

    rmq();
    for (; q; q--) {
        fin >> x >> y;
        x=first[x];
        y=first[y];
        if (x>y) i=x, x=y, y=i;
        int lg=_log(y-x+1),
            can1=seg[lg][x],
            can2=seg[lg][y-(1<<lg)+1];
        if (level[can1]<level[can2])
            fout << euler[can1];
        else
            fout << euler[can2];
        fout << '\n';
    }
    return 0;
}