Cod sursa(job #1377891)

Utilizator maribMarilena Bescuca marib Data 6 martie 2015 09:03:58
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.69 kb
#include <fstream>
#define DIM 100001
#include <vector>
using namespace std;

int euler[DIM], level[DIM], first[DIM], poz, rmq[17][DIM], n, m, log2, lg[DIM], x, y, p1, p2;

vector <int> node[DIM];

void parcurgere_euler(int vfc, int lev)
{
    euler[++poz]=vfc;
    if(poz>1)
        lg[poz]=lg[poz/2]+1;
    rmq[0][poz]=poz;
    level[poz]=lev;
    if(first[vfc]==0)
    {
        first[vfc]=poz;
    }
    for(int i=0; i<node[vfc].size(); ++i)
    {
        parcurgere_euler(node[vfc][i], lev+1);
        euler[++poz]=vfc;
        if(poz>1)
            lg[poz]=lg[poz/2]+1;
        rmq[0][poz]=poz;
        level[poz]=lev;
    }
}

void build_rmq()
{
    for(int j=1; (1<<j)<=poz; ++j)
    {
        for(int i=1; i+(1<<j)-1<=poz; ++i)
        {
            if(level[rmq[j-1][i]]<level[rmq[j-1][i+(1<<(j-1))]])
            {
                rmq[j][i]=rmq[j-1][i];
            }
            else
            {
                rmq[j][i]=rmq[j-1][i+(1<<(j-1))];
            }
        }
    }
}

int main()
{
    ifstream in("lca.in");
    ofstream out("lca.out");
    in>>n>>m;
    for(int i=2; i<=n; ++i)
    {
        int dad;
        in>>dad;
        node[dad].push_back(i);
    }
    parcurgere_euler(1, 0);
    build_rmq();
    while(m--)
    {
        in>>x>>y;
        p1=first[x]; p2=first[y];
        if(p2<p1)
            swap(p1, p2);
        log2=lg[p2-p1+1];
        if(level[rmq[log2][p1]]<level[rmq[log2][p2+1-(1<<log2)]])
        {
            out<<euler[rmq[log2][p1]]<<"\n";
        }
        else
        {
            out<<euler[rmq[log2][p2+1-(1<<log2)]]<<"\n";
        }
    }
    in.close();
    out.close();
    return 0;
}