Cod sursa(job #1959931)

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

using namespace std;

const int NMAX = 100010, SQMAX = 450;

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];
unordered_map<int, int> freq[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++;
}

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);
	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);

	int currBucket = 0, currRemainder = 0;
	for (i = 0; i < 2 * N; ++i) {
		++freq[currBucket][0];
		++currRemainder;
		if (currRemainder == bucketSize) {
			++currBucket;
			currRemainder = 0;
		}
	}

	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) {
					--freq[leftBucket][value[leftBucket * bucketSize + i]];
					value[leftBucket * bucketSize + i] += y;
					++freq[leftBucket][value[leftBucket * bucketSize + i]];
				}
				continue;
      }
      for (i = leftBucket + 1; i <= rightBucket - 1; ++i)
      	lazy[i] += y;
			for (i = leftBucketPos; i < bucketSize; ++i) {
				--freq[leftBucket][value[leftBucket * bucketSize + i]];
				value[leftBucket * bucketSize + i] += y;
				++freq[leftBucket][value[leftBucket * bucketSize + i]];
			}
			for (i = 0; i <= rightBucketPos; ++i) {
				--freq[rightBucket][value[rightBucket * bucketSize + i]];
				value[rightBucket * bucketSize + i] += y;
				++freq[rightBucket][value[rightBucket * bucketSize + i]];
			}
		} else {
			scanf("%d", &x);
			for (i = 0; i <= bucketNum; ++i) {
				if (freq[i].count(x - lazy[i])) {
					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;
}