Cod sursa(job #1468591)

Utilizator bogdan10bosBogdan Sitaru bogdan10bos Data 6 august 2015 14:21:05
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.74 kb
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <algorithm>
#include <vector>
#include <queue>
#include <deque>

#define INF ( (1 << 30) - 1 + (1 << 30) )
#define mod 666013

using namespace std;

int n, m, i, j, x, y, q;
int ap[100005], lvl[100005];
int a[300005], pt[300005], rmq[300005][22];
vector <int> v[100005];
vector <int> :: iterator it;

void E(int nod)
{
    a[ ++q ] = nod;
    ap[nod] = q;
    vector <int> :: iterator it;
    for(it = v[nod].begin(); it != v[nod].end(); it++)
    {
        int nxt = *it;
        lvl[nxt] = lvl[nod] + 1;
        E(nxt);
        a[ ++q ] = nod;
    }
}

int minlvl(int x, int y)
{
    if(lvl[x] <= lvl[y])
        return x;
    return y;
}

int main()
{
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);

    scanf("%d%d", &n, &m);
    for(i = 2; i <= n; i++)
    {
        scanf("%d", &x);
        v[x].push_back(i);
    }

    lvl[1] = 0;
    E(1);

    for(i = 1; i <= q; i++)
        rmq[i][0] = a[i];
    for(i = 1; (1 << i) <= q; i++)
        for(j = 1; j <= q - (1 << i) + 1; j++)
            rmq[j][i] = minlvl(rmq[j][i - 1], rmq[j + ( 1 << (i - 1) )][i - 1]);

    pt[1] = 0;
    pt[2] = 1;
    for(i = 3; i <= q; i++)
    {
        pt[i] = pt[i - 1];
        if(i == (2 << pt[i - 1]))
            pt[i]++;
    }

    while( m-- )
    {
        scanf("%d%d", &x, &y);
        if(x == y)
        {
            printf("%d\n", x);
            continue;
        }
        x = ap[x];
        y = ap[y];
        if(x > y)
            swap(x, y);
        printf("%d\n", minlvl( rmq[x][ pt[y - x] ] , rmq[y - (1 << pt[y - x])][ pt[y - x] ]) );
    }

    return 0;
}