Cod sursa(job #3145708)

Utilizator andrei_C1Andrei Chertes andrei_C1 Data 16 august 2023 18:42:10
Problema Arbore Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.89 kb
#include <bits/stdc++.h>

using namespace std;

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

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

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

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

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

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;
		for(int i = l; i <= r && i < llimit; i++) {
			ds[b][cnt[i]] = 0;
		}
		while(l <= r && l < llimit) {
			cnt[l] += s;
			l++;
		}
		for(int i = llimit - kB; i < n && 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;
		for(int i = l; i <= r; i++) {
			ds[b][cnt[i]] = 0;
		}
		while(l <= r) {
			cnt[l] += s;
			l++;
		}
		for(int i = ulimit; i < n && i < ulimit + kB; i++) {
			ds[b][cnt[i]] = 1;
		}
	}
}

int query(int s) {
	for(int i = 0; i * kB <= n; i++) {
		if(cnt_b[i] <= s && ds[i][s - cnt_b[i]] == 1) {
			for(int j = i * kB; j < n && 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();
	cnt = vector<int>(n);
	for(int i = 0; i * kB <= n; i++) {
		ds[i][0] = 1;
	}
	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;
}