Cod sursa(job #969660)

Utilizator narcis_vsGemene Narcis - Gabriel narcis_vs Data 4 iulie 2013 23:14:08
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.88 kb
#include <fstream>
#include <vector>

#define In "lca.in"
#define Out "lca.out"
#define Nmax 100002
#define Root 1

#define min(a,b) ((a)<(b)?(a):(b))
#define pb push_back
#define mp make_pair
#define PII pair< int , int >

using namespace std;

vector<int>Tree[Nmax];
vector < PII > Euler;

int RMQ[Nmax][18], n, N, M,pos[Nmax], Log2[2*Nmax];
ifstream f(In);

inline void Read()
{
    f>>N>>M;
    int i, X;
    for(i = 2;i <= N; ++i)
    {
        f>>X;
        Tree[X].pb(i);
    }
}

inline void _Euler(const int _node,const int height)
{
    pos[_node] = ++n;
    Euler.pb(mp(_node,height));
    vector<int>::iterator it;
    for(it = Tree[_node].begin();it!=Tree[_node].end();++it)
    {
        _Euler(*it,height+1);
        Euler.pb(mp(_node,height));
        n++;
    }
}

inline void _RMQ()
{
    int i, j, p1, p2;
    for(i = 1;i <= n; ++i)
        RMQ[i][0] = i;
    for(j = 1;(1<<j) <= n; ++j)
        for(i = 1;i + (1<<(j-1))<= n; ++i)
        {
            p1 = RMQ[i][j-1];
            p2 = RMQ[i+(1<<(j-1))][j-1];
            if(Euler[p1].second < Euler[p2].second)
                RMQ[i][j] = p1;
            else
                RMQ[i][j] = p2;
        }
    Log2[1] = 0;
    for(i = 2;i <= n; ++i)
        Log2[i] = Log2[i>>1]+1;
}

inline int Query(const int X,const int Y)
{
    int D = Y-X+1,L, p1, p2;
    L = Log2[D];
    p1 = RMQ[X][L];
    p2 = RMQ[X+D-(1<<L)][L];
    if(Euler[p1].second < Euler[p2].second)
        return Euler[p1].first;
    return Euler[p2].first;
}

inline void Write()
{
    int X, Y;
    ofstream g(Out);
    while(M--)
    {
        f>>X>>Y;
        if(pos[X]>pos[Y])
            swap(X,Y);
        g<<Query(pos[X],pos[Y])<<"\n";
    }
    f.close();
    g.close();
}

int main()
{
    Read();
    Euler.pb(mp(0,0));
    _Euler(Root,0);
    _RMQ();
    Write();
    return 0;
}