Cod sursa(job #932067)

Utilizator valentin.harsanValentin Harsan valentin.harsan Data 28 martie 2013 18:08:54
Problema Arbore Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.74 kb
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;

const int N = 100011;
const int VMAX = 1000001;
const int SIZE = 320;
const int MOD = 10007;

int nr, n, m, conv[N], cd[N], ord[N], pl[SIZE], val[N];
vector<int> v[N];
bool ver[N];
vector<pair<int, int> > h[SIZE][MOD];
char a[100], b[1000000];
int bp, bb;

void df(int nod) {
	ver[nod] = 1;
	
	conv[nod] = nr;
	ord[nr] = nod;
	++nr;
	
	for(vector<int>::iterator it = v[nod].begin(); it != v[nod].end(); ++it)
		if(!ver[*it])
			df(*it);
	
	cd[nod] = nr - 1;
}

inline bool find(int b, int poz) {
	int p = poz % MOD;
	for(vector<pair<int, int> >::iterator it = h[b][p].begin(); it != h[b][p].end(); ++it)
		if(it->first == poz)
			return it->second;
	return 0;
}

inline void addH(int b, int poz, int val) {
	int p = poz % MOD;
	
	for(vector<pair<int, int> >::iterator it = h[b][p].begin(); it != h[b][p].end(); ++it)
		if(it->first == poz) {
			it->second += val;
			return;
		}
	h[b][p].push_back(pair<int, int>(poz, val));
}

inline void make() {
	
	for(int i = 0; i < nr; i++)
		addH(i/SIZE, 0, 1);
}

inline void add(const int &cs, const int &cd, const int &va) {
	int i = cs;
	
	while(i <= cd && i % SIZE != 0) {
		int b = i / SIZE;
		
		addH(b, val[i], -1);
		val[i] += va;
		addH(b, val[i], 1);
		
		++i;
	}
	
	while(i + SIZE - 1 <= cd) {
		int b = i / SIZE;
		
		pl[b] += va;
		
		i += SIZE;
	}
	
	while(i <= cd) {
		int b = i / SIZE;
		
		addH(b, val[i], -1);
		val[i] += va;
		addH(b, val[i], 1);
		
		++i;
	}
}

inline int query(const int &sum) {
	
	for(int i = 0, j = 0, s2; i < nr; i += SIZE, ++j) {
		s2 = sum - pl[j];
		
		if(s2 < 0)
			continue;
		
		if(find(j, s2)) {
			
			for(int k = i; k < i + SIZE; ++k)
				if(val[k] == s2)
					return ord[k];
		}
		
	}
	return -1;
}

inline int ter() {
	int r = 0;
	while(a[bp] >= '0' && a[bp] <= '9')
		r = r * 10 + a[bp++] - '0';
	++bp;
	return r;
}

inline void prin(int nr) {
	if(nr == -1) {
		b[bb++] = '-';
		b[bb++] = '1';
	}
	else {
		int t[10], nu = 0;
		
		while(nr) {
			t[++nu] = nr % 10;
			nr/=10;
		}
		while(nu)
			b[bb++] = t[nu--] + '0';
	}
	b[bb++] = '\n';
}

int main() {
	int i, aa, bb, op;
	
	freopen("arbore.in", "r", stdin);
	freopen("arbore.out", "w", stdout);
	
	cin >> n >> m;
	cin.get();
	
	for(i = 1; i != n; ++i) {
		gets(a); bp = 0;
		aa = ter();
		bb = ter();
		
		v[aa].push_back(bb);
		v[bb].push_back(aa);
	}
	
	df(1);
	
	make();
	
	for(i = 1; i<=m; ++i) {
		gets(a); bp = 0;
		op = ter();
		
		if(op == 1) {
			aa = ter();
			bb = ter();
			add(conv[aa], cd[aa], bb);
		}
		else {
			bb = ter();
			prin(query(bb));
		}
	}
	
	printf("%s", b);
	
	return 0;
}