Cod sursa(job #1959940)

Utilizator RazvanR104Razvan-Andrei Ciocoiu RazvanR104 Data 10 aprilie 2017 01:28:35
Problema Arbore Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.57 kb
#include <bits/stdc++.h>

using namespace std;

const int NMAX = 100010, SQMAX = 470, VMAX = 1000010;

int N, M;
int bucketSize, bucketNum;
int pos, linear[2 * NMAX];
int first[NMAX], last[NMAX];
int lazy[SQMAX], value[NMAX];
vector<int> G[NMAX];
bitset<VMAX> check[SQMAX];

void DFS(int node, int father) {
	linear[pos] = node;
	first[node] = pos++;
	for (int it: G[node])
		if (it != father)
			DFS(it, node);
	linear[pos] = node;
	last[node] = pos++;
}

void updateBucket(int bucketPos) {
	for (int i = 0; i < bucketSize && bucketPos * bucketSize + i < 2 * N; ++i)
		check[bucketPos][value[bucketPos * bucketSize + i]] = 1;
}

int main() {
	assert(freopen("arbore.in", "r", stdin));
	assert(freopen("arbore.out", "w", stdout));

	int i, j;
	scanf("%d %d", &N, &M);
	bucketSize = sqrt(N * 2) + 1;
	bucketNum = N * 2 / bucketSize;
	for (i = 0; i < N - 1; ++i) {
		int x, y;
		scanf("%d %d", &x, &y);
		G[x].push_back(y);
		G[y].push_back(x);
	}
	DFS(1, 0);

	for (i = 0; i <= bucketNum; ++i)
		check[i][0] = 1;

	while (M--) {
		int type, x, y;
		scanf("%d", &type);
		if (type == 1) {
			scanf("%d %d", &x, &y);
      int left = first[x], right = last[x];
      int leftBucket = left / bucketSize;
      int leftBucketPos = left % bucketSize;
      int rightBucket = right / bucketSize;
      int rightBucketPos = right % bucketSize;
      if (leftBucket == rightBucket) {
				for (i = leftBucketPos; i <= rightBucketPos; ++i) {
					check[leftBucket][value[leftBucket * bucketSize + i]] = 0;
					value[leftBucket * bucketSize + i] += y;
				}
				updateBucket(leftBucket);
				continue;
      }
      for (i = leftBucket + 1; i <= rightBucket - 1; ++i)
      	lazy[i] += y;
			for (i = leftBucketPos; i < bucketSize; ++i) {
				check[leftBucket][value[leftBucket * bucketSize + i]] = 0;
				value[leftBucket * bucketSize + i] += y;
			}
			updateBucket(leftBucket);
			for (i = 0; i <= rightBucketPos; ++i) {
				check[rightBucket][value[rightBucket * bucketSize + i]] = 0;
				value[rightBucket * bucketSize + i] += y;
			}
			updateBucket(rightBucket);
		} else {
			scanf("%d", &x);
			for (i = 0; i <= bucketNum; ++i) {
				assert(x - lazy[i] < VMAX);
				if (x - lazy[i] >= 0 && check[i][x - lazy[i]]) {
					assert(x - lazy[i] >= 0);
					int seek = x - lazy[i];
					for (j = 0; j < bucketSize && i * bucketSize + j < 2 * N; ++j) {
						if (value[i * bucketSize + j] == seek) {
							cout << linear[i * bucketSize + j] << '\n';
							goto Done;
						}
					}
				}
			}
			cout << "-1\n";
			Done:;
		}
	}

	return 0;
}