Cod sursa(job #3145481)

Utilizator andrei_C1Andrei Chertes andrei_C1 Data 15 august 2023 21:26:59
Problema Arbore Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.86 kb
#include <bits/stdc++.h>

using namespace std;

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

const int kS = 1e6;
const int kB = 256;

int n, m;
vector<vector<int>> adj;

vector<int> preorder;
vector<int> tin, tout;
vector<int> cnt;
int cnt_b[kB];
bitset<1 + kS> ds[kB];

void dfs(int u = 0, int v = -1) {
	tin[u] = preorder.size();
	preorder.emplace_back(u);
	for(const auto &it: adj[u]) if(it != v) {
		dfs(it, u);
	}
	tout[u] = preorder.size();
}

void update(int u, int s) {
	int l = tin[u], r = tout[u];
	int b, llimit = (l + kB - 1) / kB * kB, ulimit = r / kB * kB;
	if(l < llimit) {
		b = l / kB;
		ds[b] = 0;
		while(l < r && l < llimit) {
			cnt[l] += s;
			l++;
		}
		for(int i = llimit - kB; i < (int) preorder.size() && i < llimit; i++) {
			ds[b][cnt[i]] = 1;
		}
	}
	while(l <= ulimit) {
		b = l / kB;
		cnt_b[b] += s;
		l += kB;
	}
	if(l < r) {
		b = l / kB;
		ds[b] = 0;
		while(l < r) {
			cnt[l] += s;
			l++;
		}
		for(int i = 1 + ulimit; i < (int) preorder.size() && i <= ulimit + kB; i++) {
			ds[b][cnt[i]] = 1;
		}
	}
}

int query(int s) {
	for(int i = 0; i * kB <= (int) preorder.size(); i++) {
		if(cnt_b[i] <= s && ds[i][s - cnt_b[i]] == 1) {
			for(int j = i * kB; j < (int) preorder.size() && j < (i + 1) * kB; j++) {
				if(cnt_b[i] + cnt[j] == s) {
					return 1 + preorder[j];
				}
			}
		}
	}
	return -1;
}

int main() {
	fin >> n >> m;
	adj = vector<vector<int>>(n);
	for(int i = 1; i < n; i++) {
		int u, v;
		fin >> u >> v;
		u--; v--;
		adj[u].emplace_back(v);
		adj[v].emplace_back(u);
	}
	tin = vector<int>(n);
	tout = vector<int>(n);
	dfs();
	// for(const auto &it: preorder) {
	// 	cout << it << " ";
	// }
	// cout << '\n';
	cnt = vector<int>(preorder.size());
	for(int i = 0; i < m; i++) {
		int t, s;
		fin >> t;
		if(t == 1) {
			int u;
			fin >> u >> s;
			u--;
			update(u, s);
		} else {
			fin >> s;
			fout << query(s) << '\n';
		}
	}
	return 0;
}