Cod sursa(job #1518962)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 6 noiembrie 2015 16:45:36
Problema Lowest Common Ancestor Scor 50
Compilator cpp Status done
Runda Arhiva educationala Marime 1.43 kb
#include <bits/stdc++.h>

using namespace std;

const int MAX_N = 100000 + 1;
const int MAX_LG = 16 + 1;

vector<int> G[MAX_N];
int depth[MAX_N];

int dad[MAX_LG][MAX_N];
int N, Q;

void dfs(int node)
{
    for (int v : G[node])
    {
        depth[v] = depth[node] + 1;
        dfs(v);
    }
}
    
int lca(int x, int y)
{
    if (depth[x] < depth[y]) //x is higher
        swap(x, y);

    if (depth[x] != depth[y])
    {
        for (int i = MAX_LG - 1; i >= 0; i--)
        {
            if (dad[i][x] != 0 && depth[ dad[i][x] ] >= depth[y])
            {
                x = dad[i][x];
            }
        }
    }
    
    assert(depth[x] == depth[y]);
    
    if (x == y)
        return x;

    for (int i = MAX_LG - 1; i >= 0; i--)
    {
        if (dad[i][x] != 0 && dad[i][x] != dad[i][y])
        {
            x = dad[i][x];
            y = dad[i][y];
        }
    }
    
    return dad[0][x];
}

int main()
{
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);
    
    cin >> N >> Q;
    
    for (int i = 2; i <= N; ++i)
    {
        cin >> dad[0][i];
        
        G[ dad[0][i] ].push_back(i);
    }
    
    dad[0][1] = 0;
    depth[1] = 1;
    dfs(1);
    
    for (int i = 1; (1 << i) <= N; ++i)
        for (int j = 1; j <= N; ++j)
            dad[i][j] = dad[i - 1][ dad[i - 1][j] ];
    
    while (Q--)
    {
        int x, y;
        cin >> x >> y;
        cout << lca(x, y) << "\n";
    }
    
	return 0;
}