Cod sursa(job #1479138)

Utilizator tamionvTamio Vesa Nakajima tamionv Data 30 august 2015 17:06:16
Problema Arbore Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.55 kb
#include <fstream>
#include <vector>
#include <unordered_map>
#include <cmath>
#include <algorithm>
using namespace std;

void make_euler(const int cur, const int prev,
	const vector<vector<int> >& vec,
	vector<int>& euler,
	vector<pair<int, int> >& st_fin){
	euler.push_back(cur);
	st_fin[cur].first = euler.size()-1;
	for(const auto next : vec[cur]){
		if(next != prev){
			make_euler(next, cur, vec, euler, st_fin); } }
	euler.push_back(cur);
	st_fin[cur].second = euler.size()-1; }

class the_structure{
	const int chunk_sz, nr_chunks;
	vector<int> buf, which_chunk;
	struct chunk_info{
		int st, dr;
		unordered_map<int, int> elements;
		int delta = 0; };
	vector<chunk_info> chunks;
	void redo_chunk(const int ch){
		chunks[ch].elements.clear();
		for(int i = chunks[ch].st; i <= chunks[ch].dr; ++i){
			chunks[ch].elements.emplace(buf[i], i); } }
public:
	the_structure(const int n):
		chunk_sz(ceil(sqrt(n))), nr_chunks(ceil(float(n)/chunk_sz)),
		buf(n), which_chunk(n), chunks(nr_chunks){

		for(int i = 0; i < nr_chunks; ++i){
			chunks[i].st = i*chunk_sz;
			chunks[i].elements.emplace(0, chunks[i].st);
			for(int j = 0; j < chunk_sz && j + chunks[i].st < n; ++j){
				which_chunk[chunks[i].st+j] = i; }
			chunks[i].dr = min(chunks[i].st + chunk_sz - 1, n-1); } }
	
	void update(const int st, const int dr, const int val){
		const int st_chunk = which_chunk[st], dr_chunk = which_chunk[dr];
		if(st_chunk != dr_chunk){
			for(int i = st; i <= chunks[st_chunk].dr; ++i){
				buf[i] += val; }
			for(int i = chunks[dr_chunk].st; i <= dr; ++i){
				buf[i] += val; }
			redo_chunk(st_chunk);
			redo_chunk(dr_chunk); }
		else{
			for(int i = st; i <= dr; ++i){
				buf[i] += val; }
			redo_chunk(st_chunk); }
		for(int i = st_chunk+1; i < dr_chunk; ++i){
			chunks[i].delta += val; } }
	
	int query(const int val){
		for(const auto& ch : chunks){
			const auto it = ch.elements.find(val-ch.delta);
			if(it != end(ch.elements)){
				return it->second; } }
		return -1; } };

int main(){
	ifstream f("arbore.in");
	ofstream g("arbore.out");
	int n, m;
	f >> n >> m;
	vector<vector<int> > vec(n);
	for(int i = 0, a, b; i < n-1; ++i){
		f >> a >> b;
		--a, --b;
		vec[a].push_back(b);
		vec[b].push_back(a); }
	vector<int> euler;
	vector<pair<int, int> > st_fin(n, {0, 0});
	make_euler(0, -1, vec, euler, st_fin);
	the_structure ts(euler.size());
	for(int i = 0, t, p, s; i < m; ++i){
		f >> t;
		if(t == 1){
			f >> p >> s;
			--p;
			ts.update(st_fin[p].first, st_fin[p].second, s); }
		else{
			f >> s;
			const int rez = ts.query(s);
			g << (rez != -1 ? euler[rez]+1 : -1) << '\n'; } }
	return 0; }