Cod sursa(job #733578)

Utilizator andunhillMacarescu Sebastian andunhill Data 12 aprilie 2012 16:24:42
Problema Stramosi Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.16 kb
#include<fstream>
#include<iostream>
#include<vector>
using namespace std;

ifstream f("stramosi.in");
ofstream g("stramosi.out");

int N, M, NrC;

vector<int>graph[350000];
vector<int>chains[350000];
vector<int>roots;
typedef vector<int>::iterator it;

int dad[350000];
int pos_in[350000];	//pos of node i in it's chain
int which[350000];	//the chain that node i belongs to
int stack[350000];

int lg[350000];
bool all[350000];

void DFS(int node)
{	int son, sum_son;
	int top = 0;
	bool leaf;
	
	stack[++top] = node;
	while(top)
	{	node = stack[top];
		
		leaf = 1; sum_son = 0;
		for(it i = graph[node].begin(); i != graph[node].end(); i++)
		{	sum_son += lg[*i];
			if(all[node] == 0)
				stack[++top] = *i;
			else if(lg[node] < lg[*i]) lg[node] = lg[*i], son = *i;
			leaf = 0;
		}
		if(all[node])
		{	lg[node] = sum_son + 1;
			chains[which[son]].push_back(node);
			which[node] = which[son];
			pos_in[node] = chains[which[son]].size() - 1;
			top--;
			continue;
		}
		
		all[node] = 1;
		if(leaf)
		{	chains[++NrC].push_back(node);
			which[node] = NrC;
			pos_in[node] = 0;
			lg[node] = 1;
			top--;
		}
	}


	/*for(it i = graph[node].begin(); i != graph[node].end(); i++)
	{	int temp = DFS(*i);
		if(max_son < temp) max_son = temp, son = *i;
	}
	
	if(max_son == 0)
	{	chains[++NrC].push_back(node);
		which[node] = NrC;
		pos_in[node] = 0;
		return 1;
	}
	
	chains[which[son]].push_back(node);
	which[node] = which[son];
	pos_in[node] = chains[which[son]].size() - 1;
	return max_son + 1;*/
}

int get(int node, int nr)
{	int chain = which[node];
	//cout<<chain<<" ";
	if(node == 0) return 0;
	if(pos_in[node] + nr < chains[chain].size()) return chains[chain][pos_in[node] + nr];
	
	return get(dad[chains[chain].back()], nr - (chains[chain].size() - pos_in[node]));
}

int main()
{	int i, j;
	int P, Q;
	
	f>>N>>M;
	for(i = 1; i <= N; i++)
	{	f>>dad[i];
		if(dad[i])
			graph[dad[i]].push_back(i);
		else roots.push_back(i);
	}
	
	for(it k = roots.begin(); k != roots.end(); k++)
		DFS(*k);
	
	for(i = 1; i <= M; i++)
	{	f>>Q>>P;
		g<<get(Q, P)<<'\n';
	}
	
	f.close();
	g.close();
	return 0;
}