Cod sursa(job #1878554)

Utilizator UrsuDanUrsu Dan UrsuDan Data 14 februarie 2017 11:42:39
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.6 kb
#include <iostream>
#include <cstdio>
#include <vector>

using namespace std;

vector< vector<int> >g(100010);

struct euler_arb{int node,depth;};
euler_arb euler[400010];

int depth[100010];
int poz[400010];
int rmq[400010][19];
int log[100010];
int k;

int minim(int a,int b)
{
    if(euler[a].depth>euler[b].depth)
        return b;
    else
        return a;
}

void dfs(int node)
{
    k++;
    euler[k].node=node;
    euler[k].depth=depth[node];
    rmq[k][0]=k;
    if(poz[node]==0)
        poz[node]=k;
    for(auto &son : g[node])
    {
        depth[son]=depth[node]+1;
        dfs(son);
        k++;
        rmq[k][0]=k;
        euler[k].node=node;
        euler[k].depth=depth[node];
    }
}

int rmq_answer(int a,int b)
{
    int over;
    if(a>b)
       swap(a,b);
    over=b-a+1;
    if(euler[rmq[a][log[over]]].depth>euler[rmq[b+1-(1<<log[over])][log[over]]].depth)
        return euler[rmq[a+1+(1<<log[over])][log[over]]].node;
    else
        return euler[rmq[a][log[over]]].node;
}

int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    int n,m,i,bit,x,y;
    scanf("%d%d",&n,&m);
    for(i=2;i<=n;i++)
    {
        scanf("%d",&x);
        g[x].push_back(i);
    }
    dfs(1);
    for(bit=1;bit<=7;bit++)
        for(i=1;i+(1<<bit)-1<=k;i++)
           rmq[i][bit]=minim(rmq[i][bit-1],rmq[i+(1<<(bit-1))][bit-1]);
    log[1]=0;
    for(i=2;i<=k;i++)
        log[i]=log[i>>1]+1;
    for(i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        printf("%d\n",rmq_answer(poz[x],poz[y]));
    }
    return 0;
}