Cod sursa(job #611666)

Utilizator mihaipopa12Popa Mihai mihaipopa12 Data 2 septembrie 2011 16:26:13
Problema Arbore Scor 100
Compilator cpp Status done
Runda Lista lui wefgef Marime 2.37 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 ( st > Lim2[i] || dr < Lim1[i] )	continue ;
		int int1,int2;
		int1 = st <= Lim1[i] ? Lim1[i] : st; int2 = dr <= Lim2[i] ? dr : Lim2[i];
		if ( int1 == Lim1[i] && int2 == Lim2[i] ){
			Ad[i] += val;
			continue ;
		}
		for ( j = Lim1[i] ; j <= Lim2[i] ; ++j ){
			P[i][Value[j]] = 0;
		}
		for ( j = Lim1[i] ; j < int1 ; ++j ){
			Value[j] += Ad[i];
			P[i][Value[j]] = 1;
		}
		for ( j = int1 ; j <= int2 ; ++j ){
			Value[j] += Ad[i] + val;
			P[i][Value[j]] = 1;
		}
		for ( j = int2 + 1 ; j <= Lim2[i] ; ++j ){
			Value[j] += Ad[i];
			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;
}