Cod sursa(job #1511644)

Utilizator akaprosAna Kapros akapros Data 26 octombrie 2015 23:13:28
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.61 kb
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define maxN 100002
#define logn 19
using namespace std;
int n, m, i, j, x, y, er[maxN * 2], pos[maxN], lev[maxN * 2], Log[maxN * 2];
int d[logn][maxN * 2];
vector < int > V[maxN];
void read()
{
    freopen("lca.in", "r", stdin);
    scanf("%d %d", &n, &m);
    for (i = 1; i < n; ++ i)
    {
        scanf("%d", &x);
        V[x].push_back(i + 1);
    }
}
void dfs(int x, int l)
{
    int i;
    er[++ er[0]] = x;
    lev[er[0]] = l;
    if (!pos[x])
       pos[x] = er[0];

    for (i = 0; i < V[x].size(); ++ i)
    {
        dfs(V[x][i], l + 1);
        er[++ er[0]] = x;
        lev[er[0]] = l;
    }
}
void solve()
{
    dfs(1, 1);
    d[0][1] = 1;
    for (i = 2; i <= er[0]; ++ i)
    {
        Log[i] = Log[i / 2] + 1;
        d[0][i] = i;
    }
     for (j = 1; j <= Log[er[0]] ; ++ j)
        for (i = 1; i + (1 << (j - 1)) <= er[0]; ++ i)
        {
            if (lev[d[j - 1][i]] < lev[d[j - 1][i + (1 << (j - 1))]])
                d[j][i] = d[j - 1][i];
            else
                d[j][i] = d[j - 1][i + (1 << (j - 1))];
        }
}
void write()
{
    int k, sol;
    freopen("lca.out", "w", stdout);
    while (m --)
    {
        scanf("%d %d", &x, &y);
        x = pos[x];
        y = pos[y];
        k = Log[y - x + 1];
        if (lev[d[k][x]] < lev[d[k][y - (1 << k) + 1]])
           sol = er[d[k][x]];
        else
            sol = er[d[k][y - (1 << k) + 1]];
        printf("%d\n", sol);
    }
}
int main()
{
    read();
    solve();
    write();
    return 0;
}