Cod sursa(job #760763)

Utilizator Theorytheo .c Theory Data 22 iunie 2012 20:32:28
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.08 kb
#include<fstream>
#include<algorithm>
#include<vector>
#define nmax  100007
#define mmax  2000006
#define foreach(V) for(vector<int>::iterator it =V.begin() ; it != V.end(); it++)
#define fort(st,dr,i) for (int i = st; i <= dr; ++i )
#define MIN(a,b) (a>b ? b : a)
using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

vector <int> v[nmax];
int N, L[nmax<<1], niv[nmax<<1] , K, pred[nmax<<1];//niv-nivelul , L-parcurgerea euler
int lg[nmax<<1], rmq[20][nmax<<1]; //rmq[i][j] - retine minimul din intervalul [j, j + i^2 -1], vectorul niv
int M;

void dfs(int nod, int nivel)
{
    L[++K] = nod;//nodul actual este adaugat in rpeprezentarea euler
    niv[K] = nivel;//niveulul fiecarei pozitii din reprezentarea euler a arborelui
    pred[nod] = K;//pozitia pe care apare prima ddata fiecare nod
    foreach(v[nod])
    {
        dfs(*it, nivel + 1);
        L[++K] = nod;
        niv[K] = nivel;

    }
}

void read()
{
    int x;
    fin >>N>> M;
    fort(2,N,i)
    {
        fin >> x;
        v[x].push_back(i);
    }
}

void LCA(int x, int y)
{
    //lca(x,y)- nivelul minim din reprezentarea euler a arborelui
    int a, b;
    a = pred[x];
    b = pred[y];
    if(a>b)
        swap(a,b);
    int dif, sh, lgg,sol;
    dif = b - a + 1;
    lgg = lg[dif];
    sh = dif - (1<<lgg);
    sol= rmq[lgg][a];
    if(niv[sol] > niv[rmq[lgg][a + sh]])
        sol = rmq[lgg][a + sh];
    fout << L[sol]<<'\n';

}

void Range_minimum_query()
{
    fort(2,K,i)
        lg[i] = lg[i/2] + 1;
    fort(1,K,i)
        rmq[0][i] = i;
    for(int i = 1; (1<<i) <= K; i++)
    {
        int l = 1 <<(i - 1 );
        int l2 = (1<<i);
        for(int j = 1; j <= K - l2 + 1  ; j++)
        {

            rmq[i][j] = rmq[i-1][j];
            if(niv[rmq[i][j]] > niv[rmq[i-1][j + l]])
                rmq[i][j] = rmq[i - 1][j + l];
        }
    }

}
int main()
{
    int x, y;
    read();
    dfs(1,0);
    Range_minimum_query();
    //fout<<"X";
    fort(1, M, i)
        fin>>x >>y , LCA(x,y);

    fin.close();
    return 0;
}