Cod sursa(job #2428982)

Utilizator luciocfLucio Cardoso Dias de Figueiredo Filho luciocf Data 7 iunie 2019 02:54:50
Problema Arbore Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 2.03 kb
#include <bits/stdc++.h>

using namespace std;

const int maxn = 1e5+10;
const int maxv = 1e6+10;
const int bucket = 320;

int n, m;

int st[maxn], en[maxn], vert[maxn], tt = -1;

int a[maxn];

int soma[maxn];

vector<int> grafo[maxn];

bitset<maxv> existe[bucket];

void dfs(int u, int p)
{
	st[u] = ++tt;
	vert[tt] = u;

	for (auto v: grafo[u])
		if (v != p)
			dfs(v, u);

	en[u] = tt;
}

int main(void)
{
	scanf("%d %d", &n, &m);

	for (int i = 1; i < n; i++)
	{
		int u, v;
		scanf("%d %d", &u, &v);

		grafo[u].push_back(v); grafo[v].push_back(u);
	}

	dfs(1, 0);

	for (int i = 0; i < n; i++)
		existe[i/bucket][0] = 1;

	for (int i = 1; i <= m; i++)
	{
		int op;
		scanf("%d", &op);

		if (op == 1)
		{
			int u, v;
			scanf("%d %d", &u, &v);

			int l = st[u], r = en[u];

			int p = l/bucket, k = r/bucket;

			if (p == k)
			{
				for (int i = l; i <= r; i++)
					existe[p][a[i]] = 0;

				for (int i = p*bucket; i < min(n, (p+1)*bucket); i++)
					if (i < l || i > r)
						existe[p][a[i]] = 1;

				for (int i = l; i <= r; i++)
				{
					a[i] += v;
					existe[p][a[i]] = 1;
				}
			}
			else
			{
				for (int i = p+1; i < k; i++)
					soma[i] += v;

				for (int i = l; i < min(n, (p+1)*bucket); i++)
					existe[p][a[i]] = 0;

				for (int i = k*bucket; i <= r; i++)
					existe[k][a[i]] = 0;

				for (int i = p*bucket; i < l; i++)
					existe[p][a[i]] = 1;

				for (int i = r+1; i < min(n, (k+1)*bucket); i++)
					existe[k][a[i]] = 1;

				for (int i = l; i < min(n, (p+1)*bucket); i++)
				{
					a[i] += v;
					existe[p][a[i]] = 1;
				}

				for (int i = k*bucket; i <= r; i++)
				{
					a[i] += v;
					existe[k][a[i]] = 1;
				}
			}
		}
		else
		{
			int v;
			scanf("%d", &v);

			bool ok = 0;

			for (int i = 0; i <= (n-1)/bucket; i++)
			{
				if (ok) break;

				if (v >= soma[i] && existe[i][v-soma[i]])
				{
					ok = 1;

					for (int j = i*bucket; j < min(n, (i+1)*bucket); j++)
					{
						if (a[j]+soma[i] == v)
						{
							printf("%d\n", vert[j]);
							break;
						}
					}
				}
			}

			if (!ok)
				printf("-1\n");
		}
	}
}