Cod sursa(job #1654927)

Utilizator tamionvTamio Vesa Nakajima tamionv Data 17 martie 2016 16:41:29
Problema Arbore Scor 15
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.51 kb
#include <cstdio>
#include <iostream>
#include <vector>
#include <bitset>
using namespace std;

void dfs(const int cur, const int prev, const vector<vector<int>>& graf,
		vector<int>& st, vector<int>& dr, vector<int>& inv, int& val){
	st[cur] = dr[cur] = val;
	inv[val++] = cur;
	for(const auto next : graf[cur]){
		if(next != prev){
			dfs(next, cur, graf, st, dr, inv, val);
			dr[cur] = dr[next]; } } }

constexpr int chunk_sz = 316, maxval = 1000010;

constexpr int get_ch(const int x){
	return x / chunk_sz; }

constexpr int first_of_chunk(const int x){
	return x * chunk_sz; }

class the_structure{
	int n, n_chunks;
	vector<int> v;
	vector<bitset<maxval>> chunks;
	vector<int> delta_chunks;
	void do_chunk(const int ch){
		chunks[ch].reset();
		for(int i = first_of_chunk(ch), lim = min(n, first_of_chunk(ch+1));
				i < lim; ++i){
			chunks[ch][v[i]] = 1; } }
public:
	the_structure(const int N): n(N), n_chunks(get_ch(n-1)+1), v(n, 0),
		chunks(n_chunks, 0), delta_chunks(n_chunks, 0){
		for(int i = 0; i < n_chunks; ++i){
			chunks[i][0] = 1; } }

	void update(int st, int dr, const int x){
		if(get_ch(st) == get_ch(dr)){
			for( ; st <= dr; ++st){
				v[st] += x; }
			do_chunk(get_ch(dr)); }
		else{
			for(int i = st, lim = min(n, first_of_chunk(get_ch(st)+1));
					i < lim; ++i){
				v[i] += x; }
			for(int i = first_of_chunk(get_ch(dr)); i <= dr; ++i){
				v[i] += x; }
			for(int i = get_ch(st)+1; i < get_ch(dr); ++i){
				delta_chunks[i] += x; }
			do_chunk(get_ch(st));
			do_chunk(get_ch(dr)); } }
	int query(const int x){
		int ch = 0;
		for( ; ch < n_chunks; ++ch){
			if(x > delta_chunks[ch] && chunks[ch][x-delta_chunks[ch]]){
				break; } }
		if(ch == n_chunks){
			return -1; }
		for(int i = first_of_chunk(ch), lim = min(n, first_of_chunk(ch+1));
				i < lim; ++i){
			if(delta_chunks[ch] + v[i] == x){
				return i; } } } };

int main(){
	FILE *f = fopen("arbore.in", "r"),
		 *g = fopen("arbore.out", "w");

	int n, m;
	fscanf(f, "%d %d ", &n, &m);

	vector<vector<int>> graf(n);
	for(int i = 0, a, b; i < n-1; ++i){
		fscanf(f, "%d %d ", &a, &b);
		--a, --b;
		graf[a].push_back(b);
		graf[b].push_back(a); }

	vector<int> st(n), dr(n), inv(n);
	{
		int val = 0;
		dfs(0, -1, graf, st, dr, inv, val); }

	static the_structure ts(n);

	for(int i = 0, t, p, s; i < m; ++i){
		fscanf(f, "%d ", &t);
		if(t == 1){
			fscanf(f, "%d %d ", &p, &s);
			--p;
			ts.update(st[p], dr[p], s); }
		else{
			fscanf(f, "%d ", &s);
			const int tmp = ts.query(s);
			fprintf(g, "%d\n", (tmp == -1 ? -1 : inv[tmp]+1)); } }
	fclose(f), fclose(g);
	return 0; }