Cod sursa(job #528708)

Utilizator DraStiKDragos Oprica DraStiK Data 3 februarie 2011 11:35:32
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.57 kb
#include <algorithm>
#include <fstream>
#include <vector>
using namespace std;

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

#define pb push_back
#define DIM 100005
#define LOG 20

int fs[DIM],eul[DIM<<1],lvl[DIM<<1],lg[DIM<<1];
int rmq[LOG][DIM<<1];
vector <int> g[DIM];
int n,m,p;


void read ()
{
    int i,x;

    fin>>n>>m;
    for (i=2; i<=n; ++i)
    {
        fin>>x;
        g[x].pb (i);
    }
}

void df_euler (int nod,int lv)
{
    vector <int> :: iterator it;

    fs[nod]=++p; eul[p]=nod; lvl[p]=lv;
    for (it=g[nod].begin (); it!=g[nod].end (); ++it)
    {
        df_euler (*it,lv+1);
        ++p; eul[p]=nod; lvl[p]=lv;
    }

}

void solve ()
{
    int i,step;

    df_euler (1,0);
    for (i=2; i<=p; ++i)
        lg[i]=lg[i>>1]+1;
    for (i=1; i<=p; ++i)
        rmq[0][i]=i;
    for (step=1; 1<<(step-1)<p; ++step)
        for (i=1; i+(1<<step)-1<=p; ++i)
            if (lvl[rmq[step-1][i]]<lvl[rmq[step-1][i+(1<<(step-1))]])
                rmq[step][i]=rmq[step-1][i];
            else
                rmq[step][i]=rmq[step-1][i+(1<<(step-1))];
}

void query ()
{
    int i,step,x,y;

    for (i=1; i<=m; ++i)
    {
        fin>>x>>y;
        x=fs[x]; y=fs[y];
        if (x>y)
            swap (x,y);

        step=lg[y-x+1];
        if (lvl[rmq[step][x]]<lvl[rmq[step][y-(1<<step)+1]])
            fout<<eul[rmq[step][x]]<<"\n";
        else
            fout<<eul[rmq[step][y-(1<<step)+1]]<<"\n";

    }
}

int main ()
{
    read ();
    solve ();
    query ();

    return 0;
}