Cod sursa(job #1221507)

Utilizator pulseOvidiu Giorgi pulse Data 20 august 2014 16:22:32
Problema Arbore Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.16 kb
#include <cstdio>
#include <vector>
#include <cstring>
#include <bitset>
#include <cmath>
#include <algorithm>

#define Low(x) (SEC * (x - 1) + 1)
#define High(x) (SEC * x)

using namespace std;

const int MAXN = 100005;
const int MAXS = 400;
int N, M, cnt;
int SEC, St[MAXN], Dr[MAXN], Sum_Sec[MAXS], Sum[MAXN], Poz[MAXN];
vector <int> G[MAXN];
bitset <MAXN> Used;
bitset <10 * MAXN> A[MAXS];

void DFS(int node)
{
	Used[node] = 1;
	St[node] = ++cnt;
	Poz[cnt] = node;
	for (vector <int> :: iterator it = G[node].begin(); it != G[node].end(); ++it)
	{
		int next = *it;
		if (!Used[next])
			DFS(next);
	}
	Dr[node] = cnt;
}

inline int Find_Sec(int a)
{
	if (a % SEC == 0)
		return a / SEC;
	return a / SEC + 1;
}

void Update_Sec(int secv, int a, int b, int s)
{
	int l = max(a, Low(secv));
	int r = min(b, High(secv));
	for (int i = Low(secv); i <= High(secv); ++i)
		A[secv][ Sum[i] ] = 0;
	for (int i = l; i <= r; ++i)
		Sum[i] += s;
	for (int i = Low(secv); i <= High(secv); ++i)
		A[secv][ Sum[i] ] = 1;
}

void Update(int a, int b, int s)
{
	for (int i = Find_Sec(a); i <= Find_Sec(b); ++i)
	{
		if (a <= Low(i) && b >= High(i))
			Sum_Sec[i] += s;
		else if (a > Low(i) && a <= High(i))
			Update_Sec(i, a, b, s);
		else if (b >= Low(i) && b < High(i))
			Update_Sec(i, a, b, s);
	}
}

int Query(int sum)
{
	for (int i = 1; i <= Find_Sec(N); ++i)
		if (Sum_Sec[i] <= sum && A[i][ sum - Sum_Sec[i] ])
		{
			for (int j = Low(i); j <= High(i) && j <= N; ++j)
				if (Sum[j] + Sum_Sec[i] == sum)
					return Poz[j];
		}
	return -1;
}

void Solve()
{
	int type, a, s;
	DFS(1);
	for (int i = 1; i <= Find_Sec(N); ++i)
		A[i][0] = 1;
	for (; M; --M)
	{
		scanf("%d", &type);
		if (type == 1)
		{
			scanf("%d %d", &a, &s);
			Update(St[a], Dr[a], s);
		}
		else
		{
			scanf("%d", &s);
			printf("%d\n", Query(s));
		}
	}
}

int main()
{
	freopen("arbore.in", "r", stdin);
	freopen("arbore.out", "w", stdout);
	scanf("%d %d\n", &N, &M);
	SEC = sqrt(N);
	for (int i = 1; i < N; ++i)
	{
		int a, b;
		scanf("%d %d\n", &a, &b);
		G[a].push_back(b);
		G[b].push_back(a);
	}
	Solve();
	return 0;
}