Cod sursa(job #1446730)

Utilizator losesUNIBUC Lacheta loses Data 2 iunie 2015 17:54:37
Problema Arbore Scor 30
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.13 kb
#include <algorithm>
#include <fstream>
#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;

const int inf = 0x3f3f3f3f, kMaxN = 1e5 + 5, kBucketSize = 400;

ifstream fin("arbore.in");
ofstream fout("arbore.out");

int Start[kMaxN], End[kMaxN], Size[kMaxN];
bool viz[kMaxN];

vector<int> vertex[kMaxN];

unordered_map<int, int> bucketVal[kMaxN / kBucketSize + 5];
int global[kMaxN / kBucketSize + 5];

int here[kMaxN];

void df(int nod) {
	Start[nod] = ++Start[0];
	here[Start[0]] = nod;
	viz[nod] = true;
	
	
	for (int itr = 0; itr < int(vertex[nod].size()); ++itr) {
		int oth = vertex[nod][itr];
		if (viz[oth]) {
			vertex[nod][itr] = vertex[nod].back();
			vertex[nod].pop_back();
			--itr;
		} else {
			df(oth);
		}
	}
	End[nod] = Start[0];
}

void Update(int st, int dr, int val) {
	int startBucket = st / kBucketSize;
	for (int bucket = startBucket, c1 = startBucket * kBucketSize + 1, c2 = (startBucket + 1) * kBucketSize; c1 <= dr; c1 += kBucketSize, c2 += kBucketSize, bucket++) {
		if (st <= c1 and c2 <= dr) {
			global[bucket] += val;
		} else {
			st = max(st, c1);
			while (st <= c2 and st <= dr) {
				bucketVal[bucket][Size[st]]--;
				Size[st] += val;
				bucketVal[bucket][Size[st]]++;
				++st;
			}
		}
	}
}

int Query(int st, int dr, int val) {
	int startBucket = st / kBucketSize;
	for (int bucket = startBucket, c1 = startBucket * kBucketSize + 1, c2 = (startBucket + 1) * kBucketSize; c1 <= dr; c1 += kBucketSize, c2 += kBucketSize, bucket++) {
		if ((st <= c1 and c2 <= dr) or (bucketVal[bucket][val - global[bucket]] != 0)) {
			st = max(st, c1);
			while (st <= c2 and st <= dr) {
				if (global[bucket] + Size[st] == val) {
					return st;
				}
				++st;
			}
		}
	}
	return 0;
}

int main() {
	int n, q; fin >> n >> q;
	for (int i = 1; i < n; ++i) {
		int a, b; fin >> a >> b;
		vertex[a].push_back(b);
		vertex[b].push_back(a);
	}
	
	df(1);

	while (q--) {
		int t; fin >> t;
		if (t == 1) {
			int p, s; fin >> p >> s;
			Update(Start[p], End[p], s);
		} else {
			int s; fin >> s;
			int ind = Query(1, n, s);
			if (ind != 0) {
				fout << here[ind] << '\n';
			} else {
				fout << "-1\n";
			}
		}
	}
	return 0;
}