Cod sursa(job #1790955)

Utilizator gabrielinelusGabriel-Robert Inelus gabrielinelus Data 28 octombrie 2016 21:40:43
Problema Lowest Common Ancestor Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 1.98 kb
#include <bits/stdc++.h>

using namespace std;
vector<vector<int>> G;
int N, M;
const int Nmax = 205005;
int logDoi[Nmax];
int depth[18][Nmax];
int node[18][Nmax];
int nre;

void eulerDecompose(int k, int lvl)
{
    ++nre;
    node[0][nre] = k;
    depth[0][nre] = lvl;

    for(auto it : G[k])
    {
        eulerDecompose(it, lvl + 1);
        ++nre;
        node[0][nre] = k;
        depth[0][nre] = lvl;
    }
}

void buildRMQ()
{
    int len = logDoi[nre];
    int IT = 1;
    for(int j = 1; j <= len; ++j) {
        for(int i = 1; i <= nre; ++i)
            if(i + IT <= nre) {
                if(depth[j - 1][i] < depth[j - 1][i + IT]) {
                    depth[j][i] = depth[j - 1][i];
                    node[j][i] = node[j - 1][i];
                }
                else {
                    depth[j][i] = depth[j - 1][i + IT];
                    node[j][i] = node[j - 1][i + IT];
                }
            }
            else {
                depth[j][i] = depth[j][i-1];
                node[j][i] = node[j][i-1];
            }
        IT <<= 1;
    }
}
int poz[201005];

int queryRMQ(int a, int b)
{
    if(a > b)
        swap(a,b);
    int lg = min(17, logDoi[b-a+1]);
    if(depth[lg][a] <= depth[lg][b - (1<<lg) + 1])
        return node[lg][a];
    return node[lg][b - (1<<lg) + 1];
}

int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);

    cin.sync_with_stdio(false);

    cin >> N >> M;
    G.resize(N + 1);

    for(int i = 2; i < Nmax; ++i)
        logDoi[i] = logDoi[i / 2] + 1;

    for(int i = 2; i <= N; ++i) {
        int x;
        cin >> x;
        G[x].push_back(i);
    }

    eulerDecompose(1, 0);
    buildRMQ();

    for(int i = 1; i <= nre; ++i)
        if(!poz[node[0][i]])
            poz[node[0][i]] = i;

    for(int i = 1; i <= M; ++i) {
        int x,y;
        cin >> x >> y;
        cout << queryRMQ(poz[x], poz[y]) << "\n";
    }

    return 0;
}