Cod sursa(job #482825)

Utilizator tamas_iuliaTamas Iulia tamas_iulia Data 5 septembrie 2010 16:35:23
Problema Arbore Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.34 kb
#include <stdio.h>
#include <math.h>
#include <vector>
#include <bitset>
#define Nmax 100005
#define Vmax 1000005
#define MIL 1000000
#define Gmax 318
#define pb push_back

using namespace std;

vector< int > v[Nmax];
bitset< Vmax > Biti[Gmax];
int Dad[Nmax],Nr[Nmax],Was[Nmax],Fii[Nmax],A[Nmax];
int Sgr[Gmax];
int N,M,nr,lg_gr,grupe;

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

void dfs(int x){
	vector< int >:: iterator it;
	Nr[x]=++nr;
	Was[nr]=x;
	
	for(it=v[x].begin(); it!=v[x].end(); ++it)
		if( *it!=Dad[x] ){
			Dad[*it]=x;
			dfs(*it);
			Fii[x] += Fii[*it]+1;
		}
}

void Add(int p,int s){
	int i,q,p_gr,u_gr,gr_p,ok;
	p=Nr[p];
	q=p+Fii[Was[p]];
	
	gr_p=p/lg_gr + (p%lg_gr >=1 );
	if( p % lg_gr != 1 ){// nu e primul elem din grupa lui
		p_gr=(gr_p-1)*lg_gr+1; // primul si ultimul
		u_gr=Minim(gr_p*lg_gr,q); // din grupa lui p
		for(i=p;i<=u_gr;++i) Biti[gr_p][A[i]]=0;
		for(i=p;i<=u_gr;++i) 
			if( A[i]+s <= MIL ) A[i]+=s;
			else A[i]=MIL+1;
		
		u_gr=gr_p*lg_gr;
		for(i=p_gr;i<=u_gr;++i) Biti[gr_p][A[i]]=1;
		
		p=u_gr+1;
		gr_p++;
	}
	//ok=0;
	while( p+lg_gr-1 <= q ){
		Sgr[gr_p] += s;
		p += lg_gr;
		gr_p++;
		//ok=1;
	}
	if(p<=q ){
		// p_gr e p
		u_gr=gr_p*lg_gr;
		for(i=p;i<=q;++i) Biti[gr_p][A[i]]=0;
		for(i=p;i<=q;++i){
			if(A[i]+s <= MIL ) A[i] +=s;
			else A[i]=MIL+1;
			Biti[gr_p][A[i]]=1;
		}
		for(i=q+1;i<=u_gr;++i) Biti[gr_p][A[i]]=1;
	}
}

void cauta(int gr,int s){
	int i,p_gr,u_gr;
	s-=Sgr[gr]; // scad cat au minim tte elem grupei
	p_gr=(gr-1)*lg_gr+1; // primul si ultimul
	u_gr=gr*lg_gr;
	for(i=p_gr;i<=u_gr;++i)
		if( A[i] == s ) break;
	printf("%d\n",Was[i]); // cine era inainte
}

int main(){
	int i,j,x,y,tip;
	freopen("arbore.in","r",stdin);
	freopen("arbore.out","w",stdout);
	scanf("%d%d",&N,&M);
	for(i=1;i<N;++i){
		scanf("%d%d",&x,&y);
		v[x].pb(y);
		v[y].pb(x);
	}
	
	dfs(1);
	
	lg_gr=(int)sqrt((double)N);
	if( lg_gr*lg_gr < N ) lg_gr++;
	grupe=N/lg_gr + ( N % lg_gr >= 1 );
	for(i=1;i<=grupe;++i) Biti[i][0]=1;
	
	for(i=1;i<=M;++i){
		scanf("%d",&tip);
		if( tip==1 ){
			scanf("%d%d",&x,&y);
			Add(x,y);
		}
		else{
			scanf("%d",&x);
			for(j=1;j<=grupe;++j)
				if( Biti[j][x-Sgr[j]] ) break;
			if( j>grupe ) printf("%d\n",-1);
			else cauta(j,x);
		}
	}
	
	fclose(stdin); fclose(stdout);
	return 0;
}