Cod sursa(job #1144560)

Utilizator gabrielinelusGabriel-Robert Inelus gabrielinelus Data 17 martie 2014 11:56:59
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.71 kb
#include <cstdio>
#include <vector>
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstring>

#define Nmax 100005
#define INF 0x3f3f3f3f

using namespace std;
int N,M,NR;
int AP[2*Nmax];
vector<int> G[Nmax];
pair<int,int> range[19][2*Nmax];
bitset<Nmax>used;
void read()
{
    int x;
    scanf("%d%d",&N,&M);
    for(int i = 2; i <= N; ++i)
    {
        scanf("%d",&x);
        G[x].push_back(i);
    }
}

void LCA(int k ,int niv)
{
    range[0][++NR] = make_pair(niv,k);
    used[k] = 1;
    for(vector<int>::iterator it = G[k].begin(); it != G[k].end();++it)
        if(!used[*it])
        {
            LCA(*it,niv+1);
            range[0][++NR] = make_pair(niv,k);
        }
}

void Build()
{

    for(int i = 1; i <= NR; ++i)
        if(!AP[range[0][i].second])
            AP[range[0][i].second] = i;

    int len =(int)log2(NR),it = 1;
    for(int k = 1; k <= len; ++k)
    {
        for(int i = 1; i <= NR; ++i)
            if(range[k-1][i] < range[k-1][i+it])
                range[k][i] = range[k-1][i];
            else
                range[k][i] = range[k-1][i+it];
        it<<=1;
    }
}

pair<int,int> Querry(int a,int b)
{
    int len =(int)log2(b-a+1);
    if(range[len][a].first < range[len][b-(1<<len)].second)
        return range[len][a];
    return range[len][b-(1<<len)];
}


int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);

    read();
    memset(range,INF,sizeof(range));
    LCA(1,0);
    Build();
    int a,b;
    for(int i = 1; i <= M; ++i)
    {
        scanf("%d%d",&a,&b);
        if(AP[a]>AP[b]) swap(a,b);
        printf("%d\n",Querry(AP[a],AP[b]).second);
    }
    return 0;
}