Cod sursa(job #1329067)

Utilizator livliviLivia Magureanu livlivi Data 28 ianuarie 2015 23:50:07
Problema Stramosi Scor 90
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.25 kb
#include<cstdio>
#define MAX 250000
using namespace std;

int dist[MAX+1];
int t[MAX+1][19];
int n;
int log;


void build(int x){
    int i=1;

    while(t[x][i]!=-1) i++;

    while((1<<i)<=dist[x] &&i<=18){
        if (t[t[x][i-1]][i-1]==-1) build(t[x][i-1]);
        t[x][i]=t[t[x][i-1]][i-1];
        i++;
    }

    while(i<=18){
        t[x][i]=0;
        i++;
    }
}


void init(){
    int i,p;
    for(i=1;i<=n;i++)
        for(p=1;p<=18;p++) t[i][p]=-1;
}


int query(int ad,int x){
    int i=0;

    if (ad>dist[x]) return 0;
    if (ad==0) return x;

    while((1<<i)<=ad) i++;

    return query(ad-(1<<(i-1)),t[x][i-1]);
}


int parinte(int x){
    if (dist[x]!=0) return dist[x];
    if (t[x][0]==0) return 0;

    dist[x]=parinte(t[x][0])+1;
    return dist[x];
}


int main(){
    freopen ("stramosi.in","r",stdin);
    freopen ("stramosi.out","w",stdout);
    int i,m,p,q;

    scanf ("%d%d",&n,&m);
    for(i=1;i<=n;i++)
        scanf ("%d",&t[i][0]);

    log=0;
    while((1<<log)<=n) log++;
    log--;

    init();

    for(i=1;i<=n;i++)
        if (dist[i]==0) dist[i]=parinte(i);

    for(i=1;i<=n;i++)
        if (t[i][log]==-1) build(i);

    for(i=1;i<=m;i++){
        scanf ("%d%d",&q,&p);
        printf ("%d\n",query(p,q));
    }

    return 0;
}