Cod sursa(job #2045998)

Utilizator andru47Stefanescu Andru andru47 Data 23 octombrie 2017 11:25:12
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.69 kb
#include <bits/stdc++.h>
using namespace std;
const int NMAX = 100005;
int rmq[20][2 * NMAX], rmqnodes[20][2 * NMAX], nodes, howmany,queries, euler[NMAX], pow2[2 * NMAX];
vector <int> g[NMAX];
inline void dfs(int node, int level)
{
    rmq[0][++howmany] = level;
    rmqnodes[0][howmany] = node;
    euler[node] = howmany;
    for (auto &it : g[node])
    {
        dfs(it, level + 1);
        rmq[0][++howmany] = level;
        rmqnodes[0][howmany] = node;
    }
    return ;
}
inline void build_rmq()
{
    for (int i = 2; i<=howmany; ++i)
        pow2[i] = pow2[i / 2] + 1;
    for (int i = 1; (1 << i) <= howmany; ++i)
        for (int j = 1; j <= howmany - (1 << i) + 1; ++j)
        {
            rmq[i][j] = min(rmq[i - 1][j], rmq[i - 1][j + (1 << (i - 1))]);
            if (rmq[i][j] == rmq[i - 1][j])
                rmqnodes[i][j] = rmqnodes[i - 1][j];
            else
                rmqnodes[i][j] = rmqnodes[i -  1][j + (1 << (i - 1))];
        }
}
inline int LCA(int x, int y)
{
    x = euler[x], y = euler[y];
    if (x > y)
        swap(x, y);
    int putere = pow2[y - x + 1];
    if (rmq[putere][x] < rmq[putere][y - (1 << putere) + 1])
        return rmqnodes[putere][x];
    return rmqnodes[putere][y - (1 << putere) + 1];
}
int main()
{
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);

    scanf("%d %d", &nodes, &queries);

    for (int i = 2; i <= nodes; ++i)
    {
        int x;
        scanf("%d", &x);
        g[x].push_back(i);
    }

    dfs(1, 1);
    build_rmq();
    for (; queries; --queries)
    {
        int x, y;
        scanf("%d %d\n", &x, &y);
        printf("%d\n", LCA(x, y));
    }
    return 0;
}