Cod sursa(job #1519019)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 6 noiembrie 2015 18:30:57
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.86 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);

    scanf("%d%d", &N, &Q);

    for (int i = 2; i <= N; ++i)
    {
        scanf("%d", &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;
        scanf("%d%d", &x, &y);
        printf("%d\n", lca(x, y));
    }

    return 0;
}