Cod sursa(job #51229)

Utilizator scapryConstantin Berzan scapry Data 10 aprilie 2007 14:54:23
Problema Stramosi Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.27 kb
#include <assert.h>
#include <stdio.h>
#include <string.h>

enum { maxn = 250001 };

struct ls
{
	int n;
	ls *next;
} *lst[maxn];

int n;
int dad[maxn];
bool v[maxn];
int depth[maxn];
int *ans[maxn];

void add(int from, int to)
{
	ls *p = new ls;
	p->n = to;
	p->next = lst[from];
	lst[from] = p;
}

void precalc(int node)
{
	if(v[node])
	{
		assert(ans[node]);
		return;
	}

	//terminal case - root
	if(dad[node] == 0)
	{
		depth[node] = 0;
		//not allocating
	}
	else
	{
		if(!v[ dad[node] ]) precalc(dad[node]);

		assert(v[ dad[node] ]);

		depth[node] = depth[ dad[node] ] + 1;

		ans[node] = new int[ depth[node] ];
		ans[node][0] = dad[node];
		memcpy(ans[node] + 1, ans[ dad[node] ], depth[ dad[node] ] * sizeof(int));
	}

	v[node] = true;

	//printf("precalc(%d) done\n", node);
}

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(i, dad[i]);
	}

	for(i = 1; i <= n; i++)
		precalc(i);

	for(i = 0; i < queries; i++)
	{
		fscanf(fi, "%d %d ", &who, &rank);
		if(rank > depth[who]) fprintf(fo, "0\n");
		else fprintf(fo, "%d\n", ans[who][rank - 1]);
	}

	fclose(fi);
	fclose(fo);
       	return 0;
}