Cod sursa(job #2657969)

Utilizator arunaaruna pop aruna Data 12 octombrie 2020 19:38:32
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.43 kb
#include <fstream>
#include <vector>
using namespace std;
ifstream cin ("lca.in");
ofstream cout ("lca.out");
vector <int> lista[100005];
int v[200005];
int rmq[200005][20], k, l[200005], poz[200005];
void dfs(int x, int lvl)
{
    v[++k] = x;
    l[k] = lvl;
    poz[x] = k;
    for (int i = 0; i < lista[x].size(); i++)
    {
        dfs(lista[x][i], lvl + 1);
        v[++k] = x;
        l[k] = lvl;
    }
}
int lg[200005];
int main()
{
    int i, n, m, j;
    cin >> n >> m;
    for (i = 2; i <= n; i++)
    {
        int x;
        cin >> x;
        lista[x].push_back(i);
    }
    dfs(1, 0);
    for (i = 1; i <= k; i++)
        rmq[i][0] = i;
    for (i = 2; i <= k; i++)
        lg[i] = lg[i / 2] + 1;
    for (j = 1; j <= lg[k]; j++)
        for (i = 1; i + (1 << j) - 1 <= k; i++)
        {
            rmq[i][j] = rmq[i + (1 << (j - 1))][j - 1];
            if (l[rmq[i][j - 1]] < l[rmq[i][j]])
                rmq[i][j] = rmq[i][j - 1];
            //cout << i << " " << i +(1 << j) - 1 << " " << rmq[i][j] << endl;
        }
    for (i = 1; i <= m; i++)
    {
        int a, b;
        cin >> a >> b;
        a = poz[a];
        b = poz[b];
        if (a > b)
            swap(a, b);
        int k = lg[max(a - b + 1, b - a + 1)];
        int ans = rmq[b - (1 << k) + 1][k];
        if (l[ans] > l[rmq[a][k]])
            ans = rmq[a][k];
        cout << v[ans] << '\n';
    }
    return 0;
}