Pagini recente » Cod sursa (job #1353103) | Cod sursa (job #3166207) | Cod sursa (job #1053576) | Cod sursa (job #2851526) | Cod sursa (job #51252)
Cod sursa(job #51252)
#include <stdio.h>
#include <string.h>
enum { maxn = 250001 };
int firstbit[maxn];
int n;
int dad[maxn];
int depth[maxn];
int ans[maxn][32]; //powers of 2 (we only need log2(E) < 19)
struct ls
{
int n;
ls *next;
} *lst[maxn];
void add(int from, int to)
{
ls *p = new ls;
p->n = to;
p->next = lst[from];
lst[from] = p;
}
void precalc_firstbit()
{
int i, bit = 0;
for(i = 0; i < maxn; i++)
{
if(i >= (1 << bit)) bit++;
firstbit[i] = bit - 1;
}
}
int calc(int node, int rank)
{
if(rank > n) return 0;
if(rank >= depth[node]) return 0;
int bit;
while(true)
{
if(rank == 0) return node;
bit = firstbit[rank];
node = ans[node][bit];
rank &= (~(1 << bit));
}
}
void precalc(int node)
{
depth[node] = depth[ dad[node] ] + 1;
for(int i = 0; i < 31; i++)
{
ans[node][i] = calc(dad[node], (1 << i) - 1);
if(ans[node][i] == 0) break; //all will be zero from now on
}
for(ls *p = lst[node]; p; p = p->next)
precalc(p->n);
}
int main()
{
int queries, i, who, rank;
FILE *fi = fopen("stramosi.in", "r"),
*fo = fopen("stramosi.out", "w");
if(!fi || !fo) return 1;
fscanf(fi, "%d%d", &n, &queries);
for(i = 1; i <= n; i++)
{
fscanf(fi, "%d", &dad[i]);
add(dad[i], i);
}
precalc_firstbit();
precalc(0); //trick: roots are "kids" of zero
for(i = 0; i < queries; i++)
{
fscanf(fi, "%d %d ", &who, &rank);
fprintf(fo, "%d\n", calc(who, rank));
}
fclose(fi);
fclose(fo);
return 0;
}