Cod sursa(job #1518964)

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

using namespace std;

const int MAX_BUFFER = 4096;

int position = MAX_BUFFER;
char buffer[MAX_BUFFER];

char getChar()
{
    if (position == MAX_BUFFER)
    {
        fread(buffer, MAX_BUFFER, 1, stdin);
        position = 0;
    }
    
    return buffer[ position++ ];
}

char getInt()
{
    int a = 0;
    char c;
    
    do
    {
        c = getChar();
        
    } while (!isdigit(c));
    
    do
    {
        a = a * 10 + (c - 48);
        c = getChar();
        
    } while (isdigit(c));
    
    return a;
}

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);
    
    N = getInt(); Q = getInt();
    
    for (int i = 2; i <= N; ++i)
    {
        dad[0][i] = getInt();
        
        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;
        x = getInt(); y = getInt();
        printf("%d\n", lca(x, y));
    }
    
	return 0;
}