Cod sursa(job #320548)

Utilizator andrei-alphaAndrei-Bogdan Antonescu andrei-alpha Data 4 iunie 2009 22:55:39
Problema Arbore Scor 50
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.49 kb
using namespace std;

#include <set>
#include <map>
#include <list>
#include <deque>
#include <stack>
#include <queue>
#include <cmath>
#include <cstdio>
#include <vector>
#include <string>
#include <bitset>
#include <utility>
#include <algorithm>

#define pb push_back
#define sz size
#define f first
#define ss second
#define II inline
#define ll long long
#define db double
#define FOR(i,a,b) for(int i=a;i<=b;++i)
#define all(v) v.begin() , v.end()
#define CC(v) memset((v),0,sizeof((v)))
#define CP(v,w) memcpy((v),(w),sizeof((w)))
#define mp make_pair

#define IN  "arbore.in"
#define OUT "arbore.out"
#define N_MAX 1<<17
int Sqrt = 1;

typedef vector<int> VI;
typedef pair<int,int> pi;
typedef vector<string> VS;

VI A[N_MAX];
int N,M,P1[N_MAX],P2[N_MAX],S[1<<18],SSqrt[1<<17],Q[1<<18];
vector<bool> viz(N_MAX);
vector< set<int> > B;

II void scan()
{
	freopen(IN,"r",stdin);
	freopen(OUT,"w",stdout);
	scanf("%d%d",&N,&M);
	
	int x,y;
	FOR(i,1,N-1)
	{
		scanf("%d%d",&x,&y);
		A[x].pb(y);
		A[y].pb(x);
	}	
	for(;Sqrt * Sqrt < N*2;++Sqrt);
	if(Sqrt > 10)
		Sqrt /= 3;
	B.resize(N*2 / Sqrt + 1);
}

II void DF(int nod)
{
	viz[nod] = true;
	
	Q[++Q[0]] = nod;
	P1[nod] = Q[0];
	
	for(VI::iterator it=A[nod].begin();it != A[nod].end();++it)
	{
		if(viz[*it])
			continue;
		DF(*it);
	}	
	
	Q[++Q[0]] = nod;
	P2[nod] = Q[0]+1;
}

II void update(int p,int s)
{
	int sum;
	int p1 = P1[p] / Sqrt;
	int p2 = P2[p] / Sqrt;
	
	FOR(i,p1+1,p2)
		SSqrt[i] += s;
	
	B[p1].clear();
	B[p2].clear();
	
	S[ P1[p] ] += s;
	S[ P2[p] ] -= s;
	
	sum = 0;
	FOR(i,Sqrt * p1,Sqrt * (p1+1) - 1)
	{
		sum += S[i];
		B[p1].insert(sum);
	}	
	
	if(p1 == p2)
		return;
	
	sum = 0;
	FOR(i,Sqrt * p2,Sqrt * (p2 + 1) - 1)
	{
		sum += S[i];
		B[p2].insert(sum);
	}	
}

II int querry(int s)
{
	FOR(p,0,Q[0] / Sqrt)
	{
		set<int>::iterator it = B[p].lower_bound(s - SSqrt[p]);
		if(*it + SSqrt[p] != s)
			continue;
		
		int sum = 0;
		FOR(i,Sqrt * p,Sqrt * (p + 1) - 1)
		{
			sum += S[i];
			if(i && sum + SSqrt[p] == s)
				return Q[i];
		}		
	}
	return -1;
}

II void solve()
{
	DF(1);
	Q[++Q[0]] = -1;
	
	FOR(i,0,Q[0] / Sqrt)
		B[i].insert(0);
	
	int tip,p,s;
	FOR(i,1,M)
	{
		scanf("%d",&tip);
		
		if(tip == 1)
		{
			scanf("%d%d",&p,&s);
			update(p,s);
			continue;
		}	
		
		scanf("%d",&s);
		printf("%d\n",querry(s) );
	}
//	printf("Time : %d ms\n",clock() );
}

int main()
{
	scan();
	solve();
	return 0;
}