Cod sursa(job #2601846)

Utilizator k2e0e0w3qDumitrescu Gheorghe k2e0e0w3q Data 15 aprilie 2020 12:18:13
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.49 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;
int t[N<<1], first[N<<1], niv[N<<1], seg[_log(N)+2][N<<1];
void go (int x) {
    euler.push_back(x);
    seen[x]=1;
    for (auto it: G[x])
        if (!seen[it]) {
            first[it]=euler.size();
            go(it);
        }
    euler.push_back(t[x]);
}

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

    int n, 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);

    n=euler.size();
    int j;
    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 (niv[euler[can1]]<niv[euler[can2]])
                seg[i][j]=can1;
            else
                seg[i][j]=can2;
        }

    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 (niv[euler[can1]]<niv[euler[can2]])
            fout << euler[can1];
        else
            fout << euler[can2];
        fout << '\n';
    }
    return 0;
}