Cod sursa(job #2134485)

Utilizator oldatlantianSerban Cercelescu oldatlantian Data 17 februarie 2018 23:43:41
Problema Arbore Scor 5
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.07 kb
#include <bits/stdc++.h>
using namespace std;

ifstream fi("arbore.in");
ofstream fo("arbore.out");

const int N = 1e5 + 5, SQR = 320, VAL = 1e6 + 5;

struct Buck {
	int lazy;
	bitset<VAL> bit; };

int n, m, lpt;

Buck bucks[SQR];
vector<int> g[N];
int value[N], line[N], lst[N], ldr[N];

static void update(int st, int dr, int val) {
	// clean st's buck
	for (int i = st - st % SQR; i / SQR == st / SQR && i <= n; ++i)
		bucks[st / SQR].bit[value[st]] = 0;

	// fill st's buck
	for (int i = st; i / SQR == st / SQR && i <= dr; ++i) {
		bucks[st / SQR].bit[value[i] + val] = 1;
		value[i]+= val; }
	for (int i = st - st % SQR; i / SQR == st / SQR && i < n; ++i) if (i < st || dr < i)
		bucks[st / SQR].bit[value[i]] = 1;

	if (st / SQR != dr / SQR) {
		// clean dr's buck
		for (int i = dr - dr % SQR; i / SQR == dr / SQR; ++i)
			bucks[dr / SQR].bit[value[i]] = 0;

		// fill dr's buck
		for (int i = min(n - 1, dr - dr % SQR + SQR - 1); i >= 0 && i / SQR == dr / SQR; --i) {
			bucks[dr / SQR].bit[value[i] + val] = 1;
			value[i]+= val; }
		for (int i = min(n - 1, dr - dr % SQR + SQR - 1); i >= 0 && i / SQR == dr / SQR; --i) if (i < st || dr < i)
			bucks[dr / SQR].bit[value[i]] = 1; }

	for (int i = st / SQR + 1; i < dr / SQR; ++i)
		bucks[i].lazy+= val; }

static int query(int val) {
	int b = -1;
	for (int i = 0; i <= n / SQR && b == -1; ++i)
		if (val >= bucks[i].lazy && bucks[i].bit[val - bucks[i].lazy])	
			b = i;

	if (b == -1) return -1;
	for (int i = b * SQR; i < (b + 1) * SQR && i < n; ++i)
		if (value[i] + bucks[b].lazy == val)
			return line[i]; }

static void _line(int u = 1, int far = 1) {
	line[lpt] = u;
	lst[u] = lpt++;
	for (auto v: g[u]) if (v != far)
		_line(v, u);
	ldr[u] = lpt - 1; }

int main() {
	int op, nod, s;

	fi >> n >> m;
	for (int a, b, i = 1; i < n; ++i) {
		fi >> a >> b;
		g[a].push_back(b);
		g[b].push_back(a); }

	_line();
	for (int i = 0; i < SQR; ++i)
		bucks[i].bit = 1;

	while (fi >> op) {
		switch(op) {
		case 1: {
			fi >> nod >> s;
			update(lst[nod], ldr[nod], s);
			break; }
		case 2: {
			fi >> s;
			fo << query(s) << '\n';
			break; } } }

	return 0; }