Cod sursa(job #466379)

Utilizator AndreyPAndrei Poenaru AndreyP Data 26 iunie 2010 13:38:34
Problema Arbore Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.54 kb
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
#define fs first
#define sc second
#define mp make_pair
#define pii pair< int,int >
#define N 100005
#define RN 320
#define pb push_back

int n,m;
int rn;
vector< int > a[N];
pii inter[N];
int cn[N];
pii v[RN][RN];
pii v1[RN],v2[RN];
int cateb;

inline void citire()
{
	scanf("%d%d",&n,&m);
	int x,y;
	for(int i=1; i<n; ++i)
	{
		scanf("%d%d",&x,&y);
		a[x].pb(y);
		a[y].pb(x);
	}
}

inline void dfs(int nod,int tata)
{
	cn[++cn[0]]=nod;
	inter[nod].fs=cn[0];
	for(size_t i=0,lim=a[nod].size(); i<lim; ++i)
	{
		if(a[nod][i]==tata)
			continue;
		dfs(a[nod][i],nod);
	}
	inter[nod].sc=cn[0];
}

inline int minim(int x,int y)
{
	return ( (x<y) ? (x) : (y) );
}

inline void update(int u,int x,int y,int cat)
{
	int nr1=0,nr2=0;
	int last=minim(rn,n-u*rn);
	for(int i=1; i<=last; ++i)
	{
		if(x<=v[u][i].sc && v[u][i].sc<=y)
		{
			v2[++nr2]=v[u][i];
			v2[nr2].fs+=cat;
		}
		else
			v1[++nr1]=v[u][i];
	}
	 int i1=1,i2=1;
	 int aux=0;
	 while(aux<last)
	 {
		 if(i1>nr1)
		 {
			 v[u][++aux]=v2[i2];
			 ++i2;
		 }
		 else
		 if(i2>nr2)
		 {
			 v[u][++aux]=v1[i1];
			 ++i1;
		 }
		 else
		 if(v1[i1].fs<=v2[i2].fs)
		 {
			 v[u][++aux]=v1[i1];
			 ++i1;
		 }
		 else
		 {
			 v[u][++aux]=v2[i2];
		     ++i2;
		 }
	 }
}

inline void updateBig(int x,int y,int cat)
{
	for(int i=x; i<=y; ++i)
		v[i][0].fs+=cat;
}

inline int caut(int u,int cat)
{
	if(v[u][0].fs>cat)
		return 0;
	cat-=v[u][0].fs;
	int pr=1;
	int ul=minim(rn,n-u*rn);
	if(v[u][pr].fs==cat)
		return v[u][pr].sc;
	if(v[u][ul].fs==cat)
		return v[u][ul].sc;
	if(cat<v[u][pr].fs || v[u][ul].fs<cat)
		return 0;
	int m;
	while(pr<ul)
	{
		m=(pr+ul)>>1;
		if(cat<=v[u][m].fs)
			ul=m;
		else
			pr=m+1;
	}

	if(v[u][pr].fs!=cat)
	{
		if(v[u][pr].fs<cat)
		{
			if(pr!=minim(rn,n-u*rn))
				++pr;
			else
				return 0;
		}
		else
		{
			if(pr!=1)
				--pr;
			else
				return 0;
		}
		if(v[u][pr].fs!=cat)
			return 0;
	}

	return v[u][pr].sc;
}

inline void rezolva()
{
	int cod,x,y;
	int aux1,aux2,aux11,aux22;
	int x1,y1;
	int last;
	for(int i=0; i<m; ++i)
	{
		scanf("%d",&cod);
		if(cod==1)
		{
			scanf("%d%d",&x,&y);
			aux1=inter[x].fs;
			aux2=inter[x].sc;
			x1=aux1/rn;
			y1=aux2/rn;
			if(aux1%rn==0)
				--x1;
			if(aux2%rn==0)
				--y1;

			if(x1+1<y1)
				updateBig(x1+1,y1-1,y);
			aux11=aux1%rn;
			aux22=aux2%rn;
			if(aux11==0)
				aux11=rn;
			if(aux22==0)
				aux22=rn;
			if(x1==y1)
			{
				last=minim(rn,n-x1*rn);
				if(aux11==1 && aux22==last)
					updateBig(x1,x1,y);
				else
					update(x1,aux1,aux2,y);
				continue;
			}

			last=minim(rn,n-x1*rn);
			if(aux11==1)
				updateBig(x1,x1,y);
			else
				update(x1,aux1,x1*rn+last,y);

			last=minim(rn,n-y1*rn);
			if(aux22==last)
				updateBig(y1,y1,y);
			else
				update(y1,1+y1*rn,aux2,y);
			continue;
		}

		scanf("%d",&x);
		y=0;
		for(int j=0; j<cateb && y==0; ++j)
		{
			y=caut(j,x);
			if(y==0)
				continue;
			printf("%d\n",cn[y]);
		}
		if(y==0)
			printf("-1\n");
	}
}

int main()
{
	freopen("arbore.in","r",stdin);
	freopen("arbore.out","w",stdout);

	citire();
	dfs(1,0);
	rn=(int)sqrt((double)n);
	if(rn*rn<n)
		++rn;
	cateb=n/rn+( (n%rn!=0) ? 1 : 0 );
	int last;
	int aux=0;
	for(int i=0; i<cateb; ++i)
	{
		last=minim(rn,n-i*rn);
		for(int j=1; j<=last; ++j)
			v[i][j].sc=++aux;
	}
	rezolva();

	return 0;
}