Cod sursa(job #923669)

Utilizator SpiriFlaviuBerbecariu Flaviu SpiriFlaviu Data 23 martie 2013 18:48:18
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.36 kb
#include <fstream>
#include <vector>

using namespace std;

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

vector<int> v[100001];
int auxn,n,euler[3*100001],m,x,y, nivel[3*100001];
int rmq[3*100001][24];
int log[3*100001];
int f[3*100001];

void create_euler(int nod,int niv)
{
    euler[++auxn] = nod;
    f[nod] = auxn;
    nivel[auxn] = niv;
    for(unsigned int i=0;i<v[nod].size();i++)
    {
        create_euler(v[nod][i],niv+1);
        euler[++auxn] = nod;
        nivel[auxn] = niv;
    }
}

int main()
{
    fin>>n>>m;
    for(int i=2;i<=n;i++)
    {
        fin>>x;
        v[x].push_back(i);
    }
    create_euler(1,0);
    n = auxn;
    for(int i=1;i<=n;i++)
    {
        rmq[i][0] = i;
        if(i>1)
            log[i] = 1+log[i>>1];
    }
    for(int j=1;(1<<j)<=n;j++)
        for(int i=1;i+(1<<j)-1<=n;i++)
            if(nivel[ rmq[i][j-1] ] < nivel[  rmq[i + (1<<(j-1)) -1][j-1] ])
                rmq[i][j] = rmq[i][j-1];
            else rmq[i][j] = rmq[i + (1<<(j-1))-1][j-1];
    for(int i=1;i<=m;i++)
    {
        fin>>x>>y;
        x = f[x],y = f[y];
        int l = log[y-x+1];
        if(nivel[rmq[x][l]] < nivel[rmq[y - (1<<l)+1][l]])
            fout<<euler[rmq[x][l]];
        else fout<<euler[rmq[y-(1<<l)+1][l]];
        fout<<'\n';
    }

    fin.close();
    fout.close();
    return 0;
}