Cod sursa(job #445713)

Utilizator Mishu91Andrei Misarca Mishu91 Data 24 aprilie 2010 12:16:08
Problema Arbore Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.96 kb
#include <fstream>
#include <vector>
#include <bitset>
#include <cmath>

using namespace std;

#define foreach(V) for(typeof (V).begin() it = (V).begin(); it != (V).end(); ++it)

const int MAX_N = 100005;
const int MAX_Q = 1000005;
const int MAX_S = 360;

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

int N, M, X, S, E[MAX_N], C[MAX_N], B[MAX_S], St[MAX_N], Dr[MAX_N], Li[MAX_S], Lf[MAX_S];
vector <int> G[MAX_N];
bitset <MAX_Q> P[MAX_S];

void citire() {
	fin >> N >> M;

	for(int i = 1; i < N; ++i) {
		int a, b;
		fin >> a >> b;
		G[a].push_back(b);
		G[b].push_back(a);
	}
}

void dfs(int nod, int t) {
	St[nod] = ++X;
	E[X] = nod;

	foreach(G[nod])
		if(*it != t) 
			dfs(*it, nod);

	Dr[nod] = X;
}

void pre() {
	S = sqrt(N);

	Li[1] = 1;
	Lf[1] = S;

	int nr = 0;
	for(int i = 2; Li[i-1] <= N; ++i) {
		Li[i] = Li[i-1]+S;
		Lf[i] = min(Lf[i-1]+S, N);
		nr = i;
	}

	S = nr-1;
	for(int i = 1; i <= S; ++i)
		P[i][0] = 1;
}

void update_part(int ind, int li, int lf, int s) {
	for(int i = Li[ind]; i <= Lf[ind]; ++i) {
		P[ind][C[i]] = 0;
	}

	for(int i = li; i <= lf; ++i)
		C[i] += s;
	for(int i = Li[ind]; i <= Lf[ind]; ++i) {
		P[ind][C[i]] = 1;
	}
}

void update(int li, int lf, int s) {
	for(int i = 1; i <= S; ++i)
		if(li <= Li[i] && Lf[i] <= lf)
			B[i] += s;

		else if(Li[i] <= li && li <= Lf[i]) {
			int st = li;
			int dr = min(lf, Lf[i]);
			update_part(i, st, dr, s);
		} 
		else if(Li[i] <= lf && lf <= Lf[i]) {
			int st = max(li, Li[i]);
			int dr = lf;
			update_part(i, st, dr, s);
		}
}

int query(int s) {
	for(int i = 1; i <= S; ++i) {
		int cst = s - B[i];
		if(cst < 0 || P[i][cst] == 0)
			continue;

		for(int j = Li[i]; j <= Lf[i]; ++j)
			if(C[j] == cst)
				return E[j];
	}

	return -1;
}

void solve() {
	for(int i = 1; i <= M; ++i) {
		int t;
		fin >> t;
		if(t == 2) {
			int x;
			fin >> x;
			fout << query(x) << "\n";
		} else {
			int p, s;
			fin >> p >> s;
			update(St[p], Dr[p], s);
		}
	}
}

int main() {
	citire();
	dfs(1, 0);
	pre();
	solve();
}