Cod sursa(job #616527)

Utilizator ChallengeMurtaza Alexandru Challenge Data 12 octombrie 2011 19:48:56
Problema Arbore Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.28 kb
#include <fstream>
#include <bitset>
#include <vector>

using namespace std;

const char InFile[]="arbore.in";
const char OutFile[]="arbore.out";
const int MaxN=100111;
const int MaxS=1000111;
const int SqrtMaxN=400;

ifstream fin(InFile);
ofstream fout(OutFile);

int N,M,x,y,rs,V[MaxN],ST[MaxN],SF[MaxN],SQRT_ST[SqrtMaxN],SQRT_SF[SqrtMaxN],SQRT_S[SqrtMaxN],S[MaxN];
vector<int> A[MaxN];
bitset<MaxS> rad[SqrtMaxN],viz;

void DFS(int nod)
{
	ST[nod]=++V[0];
	V[V[0]]=nod;
	viz[nod]=1;
	for(vector<int>::iterator it=A[nod].begin();it!=A[nod].end();++it)
	{
		if(!viz[*it])
		{
			DFS(*it);
		}
	}
	SF[nod]=V[0];
}

inline void build()
{
	rs=0;
	while(rs*rs<=N)
	{
		++rs;
	}
	--rs;

	int ind=0;
	int st=1;
	while(st<=N)
	{
		++ind;
		SQRT_ST[ind]=st;
		SQRT_SF[ind]=st+rs-1,N;
		st+=rs;
	}
	rs=ind;
	if(SQRT_SF[ind]>N)
	{
		SQRT_SF[ind]=N;
	}

	for(register int i=1;i<=rs;++i)
	{
		rad[i][0]=1;
	}
}

inline int query()
{
	for(register int i=1;i<=rs;++i)
	{
		if(x<SQRT_S[i])
		{
			continue;
		}
		if(rad[i][x-SQRT_S[i]])
		{
			x-=SQRT_S[i];
			for(register int j=SQRT_ST[i];j<=SQRT_SF[i];++j)
			{
				if(x==S[j])
				{
					return V[j];
				}
			}
		}
	}
	return -1;
}

inline void update(int st, int dr)
{
	int ust=N+1;
	int udr=0;
	for(register int i=1;i<=rs;++i)
	{
		if(dr<SQRT_ST[i] || SQRT_SF[i]<st)
		{
			continue;
		}
		if(st<=SQRT_ST[i] && SQRT_SF[i]<=dr)
		{
			SQRT_S[i]+=x;
			continue;
		}
		int intst=max(st,SQRT_ST[i]);
		int intdr=min(dr,SQRT_SF[i]);
		for(register int j=SQRT_ST[i];j<=SQRT_SF[i];++j)
		{
			rad[i][S[j]]=0;
		}
		for(register int j=SQRT_ST[i];j<intst;++j)
		{
			S[j]+=SQRT_S[i];
			rad[i][S[j]]=1;
		}
		for(register int j=intdr+1;j<=SQRT_SF[i];++j)
		{
			S[j]+=SQRT_S[i];
			rad[i][S[j]]=1;
		}
		for(register int j=intst;j<=intdr;++j)
		{
			S[j]+=SQRT_S[i]+x;
			rad[i][S[j]]=1;
		}
		SQRT_S[i]=0;
	}
}

int main()
{
	fin>>N>>M;
	for(register int i=1;i<N;++i)
	{
		fin>>x>>y;
		A[x].push_back(y);
		A[y].push_back(x);
	}
	DFS(1);
	build();
	for(register int i=1;i<=M;++i)
	{
		fin>>x;
		if(x==1)
		{
			fin>>y>>x;
			update(ST[y],SF[y]);
		}
		else
		{
			fin>>x;
			fout<<query()<<"\n";
		}
	}
	fin.close();
	fout.close();
	return 0;
}