Cod sursa(job #611659)

Utilizator mihaipopa12Popa Mihai mihaipopa12 Data 2 septembrie 2011 16:14:25
Problema Arbore Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.99 kb
#include<stdio.h>
#include<vector>
#include<bitset>

#define maxN 100005
#define maxSqrt 320
#define maxVal 1000005

using namespace std;

FILE*f=fopen("arbore.in","r");
FILE*g=fopen("arbore.out","w");

int n,m,i,j,x,y,ind,ii,tip,val,rad;
int A[maxN],B[maxN],V[maxN],Ad[maxSqrt],Value[maxN],Lim1[maxSqrt],Lim2[maxSqrt];
bitset<maxN>viz; bitset<maxVal>P[maxSqrt];
vector<int>G[maxN];

inline void citire () {
	
	fscanf(f,"%d %d",&n,&m);
	for ( i = 1 ; i < n ; ++i ){
		fscanf(f,"%d %d",&x,&y);
		G[x].push_back(y); G[y].push_back(x);
	}
}

void dfs ( int nod ){
	
	viz[nod] = 1; V[++ind] = nod; A[nod] = ind;
	
	for ( int i = 0 ; i < G[nod].size() ; ++i ){
		if ( !viz[ G[nod][i] ] ){
			dfs( G[nod][i] );
		}
	}
	B[nod] = ind;
}

inline void div_sqrt () {
	
	for ( rad = 0; (rad+1)*(rad+1) <= n ; ++rad );
	
	for ( i = 1 ; i <= rad ; ++i ){
		Lim1[i] = Lim2[i-1] + 1;
		Lim2[i] = Lim1[i] + rad - 1;
	}
	
	if ( rad * rad != n ){
		++rad; Lim1[rad] = Lim2[rad-1] + 1; Lim2[rad] = n;
	}
}

inline void update ( int st , int dr , int val ){
	
	for ( i = 1 ; i <= rad ; ++i ){
		if ( Lim1[i] < st && dr < Lim2[i] ){
			for ( j = Lim1[i] ; j <= Lim2[i] ; ++j ){
				P[i][Value[j]] = 0;
			}
			for ( j = Lim1[i] ; j < st ; ++j ){
				Value[j] += Ad[i]; P[i][Value[j]] = 1;
			}
			for ( j = st ; j <= dr ; ++j ){
				Value[j] += Ad[i] + val; P[i][Value[j]] = 1;
			}
			for ( j = dr + 1 ; j <= Lim2[i] ; ++j ){
				Value[j] += Ad[i]; P[i][Value[j]] = 1;
			}
			break ;
		}
		if ( st <= Lim1[i] && Lim2[i] <= dr ){
			Ad[i] += val;
		}
		else{
			if ( st > Lim1[i] && st <= Lim2[i] ){
				for ( j = Lim1[i] ; j <= Lim2[i] ; ++j ){
					P[i][Value[j]] = 0;
				}
				for ( j = Lim1[i] ; j < st ; ++j ){
					Value[j] += Ad[i];
					P[i][Value[j]] = 1;
				}
				for ( j = st ; j <= Lim2[i] ; ++j ){
					Value[j] += Ad[i] + val;
					P[i][Value[j]] = 1;
				}
				Ad[i] = 0;
			}
			else{
				if ( dr >= Lim1[i] && st < Lim1[i] && dr <= Lim2[i] ){
					for ( j = Lim1[i] ; j <= Lim2[i] ; ++j ){
						P[i][Value[j]] = 0;
					}
					for ( j = dr + 1 ; j <= Lim2[i] ; ++j ){
						Value[j] += Ad[i];
						P[i][Value[j]] = 1;
					}
					for ( j = Lim1[i] ; j <= dr ; ++j ){
						Value[j] += Ad[i] + val;
						P[i][Value[j]] = 1;
					}
					Ad[i] = 0;
				}
			}
		}
	}
}

inline int query ( int val ){
	
	for ( i = 1 ; i <= rad ; ++i ){
		if ( val - Ad[i] < 0 )	continue ;
		if ( P[i][val - Ad[i]] ){
			for ( j = Lim1[i] ; j <= Lim2[i] ; ++j ){
				if ( Value[j] + Ad[i] == val )
					return V[j];
			}
		}
	}
	return -1;
}

inline void solve () {
	
	for ( i = 1 ; i <= rad ; ++i )	P[i][0] = 1;
	
	for ( ii = 1 ; ii <= m ; ++ii ){
		fscanf(f,"%d",&tip);
		if ( tip == 1 ){
			fscanf(f,"%d %d",&x,&val);
			update(A[x],B[x],val);
		}
		else{
			fscanf(f,"%d",&val);
			fprintf( g,"%d\n",query(val) );
		}
	}
}

int main () {
	
	citire();
	dfs(1);
	div_sqrt();
	solve();
	
	fclose(f);
	fclose(g);
	
	return 0;
}