Cod sursa(job #929880)

Utilizator dicu_dariaDaria Dicu dicu_daria Data 27 martie 2013 12:29:12
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.37 kb
#include <fstream>
#include <vector>

using namespace std;

int n, m, i, k, c, j, x, y, sol;
int Euler[1000010], tata[100010], First[1000010], Nod[1000010], rmq[1000010][20], Log[1000010];
vector<int> G[100010];

void DF(int x, int level)
{
    vector<int> :: iterator it;
    Euler[++k] = level;
    First[x] = k;
    Nod[k] = x;
    for(it = G[x].begin(); it != G[x].end(); ++it)
    if(*it != tata[x])
    {
        DF(*it, level+1);
        Euler[++k] = level;
        Nod[k] = x;
    }
}

int main()
{
    ifstream fi("lca.in");
    ofstream fo("lca.out");
    fi >> n >> m;
    for(i = 2; i <= n; i++)
    {
        fi >> tata[i];
        G[tata[i]].push_back(i);
    }
    DF(1, 1);
    for(i = 2; i <= k; i++) Log[i] = Log[i/2] + 1;
    for(i = 1; i <= k; i++) rmq[i][0] = i;
    for(c = 1; (1<<c) <= k; c++)
    {
        for(i = 1; i <= k; i++)
        {
            rmq[i][c] = rmq[i][c-1];
            j = i + (1<<(c-1));
            if(j <= k and Euler[rmq[j][c-1]] < Euler[rmq[i][c]]) rmq[i][c] = rmq[j][c-1];
        }
    }
    while(m--)
    {
        fi >> x >> y;
        x = First[x]; y = First[y];
        if(x > y) swap(x, y);
        c = Log[y - x + 1];
        sol = rmq[x][c];
        j = y - (1<<c) + 1;
        if(Euler[sol] > Euler[rmq[j][c]]) sol = rmq[j][c];
        fo << Nod[sol] << "\n";
    }
    return 0;
}