Cod sursa(job #1112563)

Utilizator kiralalaChitoraga Dumitru kiralala Data 19 februarie 2014 20:51:48
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.38 kb
#include <fstream>
#include <vector>
#define NMAX 100005
#define MMAX 2000005

using namespace std;

FILE* f=freopen("lca.in","r",stdin);
FILE* o=freopen("lca.out","w",stdout);

int n,m;
vector<int> graph[NMAX];
int eul[MMAX],l;
int poz[NMAX];
bool vis[NMAX];
int mat[NMAX][17];

int logbin(int x)
{
    int r=-1;
    for(int i=1;i<=x;i<<=1) r+=1;
    return r;
}
int minim(int a, int b)
{
    return (a<b)?a:b;
}

void EulerWalking(int x)
{
    eul[++l]=x;
    poz[x]=l;
    vis[x]=1;
    for(int i=0;i<graph[x].size();++i)
    {
        if(!vis[graph[x][i]]) {
            EulerWalking(graph[x][i]);
            eul[++l]=x;
        }
    }
}

void GenRMQ()
{
    for(int i=1;i<=l;++i)
    {
        mat[0][i]=eul[i];
    }
    for(int i=1;i<=logbin(l);++i)
    {
        for(int j=1;j+(2<<i)<=l;j+=1)
        {
            mat[i][j]=minim(mat[i-1][j],mat[i-1][j+(2<<(i-1))]);
        }
    }
}

int rmq(int pa, int pb)
{
    int c=logbin(pb-pa+1);
    return minim(mat[c][pa],mat[c][pb-(2<<c)+1]);
}

int main()
{
    scanf("%d%d",&n,&m);

    for(int i=2;i<=n;++i)
    {
        int x;
        scanf("%d",&x);

        graph[x].push_back(i);
    }

    EulerWalking(1);
    GenRMQ();

    for(int i=0;i<m;++i)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        printf("%d\n",rmq(poz[a],poz[b]));
    }

    return 0;
}