Cod sursa(job #1282055)

Utilizator vladrochianVlad Rochian vladrochian Data 3 decembrie 2014 22:12:02
Problema Arbore Scor 100
Compilator cpp Status done
Runda Lista lui wefgef Marime 1.85 kb
#include <fstream>
#include <vector>
#include <bitset>
#include <cmath>
using namespace std;

const int kMaxN = 100005, kMaxSqrt = 320, kMaxVal = 1000005;

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

int N, M, v[kMaxN], crt_pos, tree_first[kMaxN], tree_last[kMaxN];
vector<int> G[kMaxN];
int sqrtN, lists, list_first[kMaxSqrt], list_last[kMaxSqrt];
bitset<kMaxVal> is_val[kMaxSqrt];
int list_value[kMaxSqrt], node_value[kMaxN];

void DFS(int node, int father) {
	v[++crt_pos] = node;
	tree_first[node] = crt_pos;
	for (int i : G[node])
		if (i != father)
			DFS(i, node);
	tree_last[node] = crt_pos;
}

void Update(int l, int r, int u) {
	for (int i = 1; i <= lists; ++i) {
		int first = list_first[i], last = list_last[i];
		if (last < l)
			continue;
		if (r < first)
			return;
		if (l <= first && last <= r) {
			list_value[i] += u;
			continue;
		}
		for (int j = max(first, l); j <= min(last, r); ++j) {
			is_val[i][node_value[j]] = false;
			node_value[j] += u;
		}
		for (int j = first; j <= last; ++j)
			is_val[i][node_value[j]] = true;
	}
}

int Query(int q) {
	for (int i = 1; i <= lists; ++i)
		if (list_value[i] <= q && is_val[i][q - list_value[i]])
			for (int j = list_first[i]; j <= list_last[i]; ++j)
				if (list_value[i] + node_value[j] == q)
					return v[j];
	return -1;
}

int main() {
	fin >> N >> M;
	for (int i = 1; i < N; ++i) {
		int x, y;
		fin >> x >> y;
		G[x].push_back(y);
		G[y].push_back(x);
	}
	DFS(1, 0);
	sqrtN = sqrt(N);
	for (int i = 1; i <= N; i += sqrtN) {
		++lists;
		list_first[lists] = i;
		list_last[lists] = min(i + sqrtN - 1, N);
		is_val[lists][0] = true;
	}
	while (M--) {
		int t, p, s;
		fin >> t;
		if (t == 1) {
			fin >> p >> s;
			Update(tree_first[p], tree_last[p], s);
		} else {
			fin >> s;
			fout << Query(s) << "\n";
		}
	}
	return 0;
}