Cod sursa(job #2032814)

Utilizator caesar2001Stoica Alexandru caesar2001 Data 5 octombrie 2017 18:30:53
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.82 kb
#include <cstdio>

using namespace std;

FILE *in,*out;

const int nmax = 100005;
const int logmax = 20;

int last[nmax],dest[nmax],next[nmax],cont,euler[2*nmax],pos[nmax*2];
int rmq[nmax*4][logmax],lg[nmax*2];

void buildtree(int dad,int node)
{
    cont ++;
    dest[cont] = node;
    next[cont] = last[dad];
    last[dad] = cont;
}

int ind;

void computeeuler(int node)
{
    if(node != 0)
    {
        euler[++ind] = node;
        if(pos[node] == 0)
            pos[node] = ind;
        int x = last[node];
        while(x != 0)
        {
            computeeuler(dest[x]);
            euler[++ind] = node;
            x = next[x];
        }
    }
}

void precompute()
{
    for(int i = 2;i <= ind;i ++)
        lg[i] = lg[i >> 1] + 1;
}
int min(int a,int b)
{
    if(a < b)
        return a;
    return b;
}

void computermq()
{
    for(int i = 1;i <= ind;i ++){
        rmq[i][0] = euler[i];
    }
    precompute();
    for(int j = 1;j <= lg[ind];j ++){
        for(int i = 1;i <= ind;i ++){
            rmq[i][j] = min(rmq[i][j-1],rmq[i + (1 << (j-1))][j-1]);
        }
    }
}

int main()
{
    in = fopen("lca.in","r");
    out = fopen("lca.out","w");
    int n,m;
    fscanf(in,"%d %d",&n,&m);
    for(int i = 1; i < n; i ++)
    {
        int x;
        fscanf(in,"%d",&x);
        buildtree(x,i+1);
    }
    computeeuler(1);
    computermq();
    for(int i = 1;i <= m;i ++)
    {
        int x,y;
        fscanf(in,"%d %d",&x,&y);
        int node1 = pos[x];
        int node2 = pos[y];
        if(node1 > node2)
        {
            int aux = node2;
            node2 = node1;
            node1 = aux;
        }
        int dif = lg[node2-node1];
        fprintf(out,"%d\n",min(rmq[node1][dif],rmq[node2- (1 << dif) + 1][dif]));
    }
    return 0;
}