Cod sursa(job #339589)

Utilizator CezarMocanCezar Mocan CezarMocan Data 10 august 2009 15:02:39
Problema Arbore Scor 100
Compilator cpp Status done
Runda Lista lui wefgef Marime 2.79 kb
#include <cstdio>
#include <bitset>
#include <vector>
#include <math.h>
#include <iostream>
#define maxn 100010
#define maxs 320

using namespace std;

int n, m, a, b, i, j, sq, tip, p, s, bf;
vector <int> g[maxn];
bitset <10 * maxn> bs[maxs]; //aici tin siru de 1 si 0, daca am sau nu un anumit numar
int add_buc[maxs]; //aici tin cat adun pe fiecare bucata de sqrt
int x[maxn]; //aici tin cat adun pe numerele separate
int pdf[maxn], st[maxn], dr[maxn];
bool viz[maxn];

void df(int nod) {
	int i, fiu;
	if (viz[nod])
		return;
	viz[nod] = 1;
	a++;
	pdf[a] = nod;
	st[nod] = a;

	for (i = 0; i < g[nod].size(); i++) {
		fiu = g[nod][i];
		df(fiu);
	}

	dr[nod] = a;
}

inline void update_bitset(int buc, int stg, int drt, int us, int ud, int s) {
	int i;
	//golesc bitsetul
	for (i = stg; i <= drt; i++)
		bs[buc][x[i]] = 0;
	//parcurg numerele, le updatez
	for (i = us; i <= ud; i++) 
		x[i] += s;
	//refac bitsetu
	for (i = stg; i <= drt; i++)
		bs[buc][x[i]] = 1;
}

inline void get_poz(int poz, int &buc, int &st, int &dr) {
	buc = (poz - 1) / sq + 1;
	st = (buc - 1) * sq + 1;
	dr = buc * sq;
	if (dr > n)
		dr = n;
}

inline void update(int nod, int sum) {
	int stg1, drt1, stg2, drt2, buc1, buc2, i;

	get_poz(st[nod], buc1, stg1, drt1);
//	fprintf(stderr, "%d  %d %d %d\n", nod, buc1, stg1, drt1);

	get_poz(dr[nod], buc2, stg2, drt2);
//	fprintf(stderr, "%d  %d %d %d\n", nod, buc2, stg2, drt2);
	if (buc2 != buc1) {
		update_bitset(buc1, stg1, drt1, st[nod], drt1, sum);
		update_bitset(buc2, stg2, drt2, stg2, dr[nod], sum);
	}
	else {
		for (i = stg1; i <= drt1; i++)
			bs[buc1][x[i]] = 0;
		for (i = st[nod]; i <= dr[nod]; i++) 
			x[i] += sum;
		for (i = stg1; i <= drt1; i++)
			bs[buc1][x[i]] = 1;
	}
	

	for (i = buc1 + 1; i < buc2; i++)
		add_buc[i] += sum;
}

int query(int sum) {
	int buc, found = 0, i, st, dr;
	for (i = 1; i <= bf; i++) 
		if (sum - add_buc[i] >= 0)
			if (bs[i][sum - add_buc[i]] == 1) {
				found = i;
				break;
			}

	if (found == 0)
		return -1;

	buc = found;
	st = (found - 1) * sq + 1;
	dr = found * sq;

	found = 0;
	for (i = st; i <= dr; i++)
		if (x[i] == sum - add_buc[buc]) {
			found = i;
			break;
		}

	return pdf[found];
}

int main() {
	freopen("arbore.in", "r", stdin);
	freopen("arbore.out", "w", stdout);

	scanf("%d%d", &n, &m);
	sq = (int) sqrt(n);
	get_poz(n, bf, a, b);
	for (i = 1; i <= bf; i++)
		bs[i][0] = 1;

	for (i = 1; i < n; i++) {
		scanf("%d%d", &a, &b);
		g[a].push_back(b);
		g[b].push_back(a);
	}

	a = 0;
	df(1);

/*	for (i = 1; i <= n; i++)
		fprintf(stderr, "%d: %d %d\n", i, st[i], dr[i]);*/

	for (i = 1; i <= m; i++) {
		scanf("%d", &tip);
//		fprintf(stderr, "%d\n", i);
		if (tip == 1) {
			scanf("%d%d", &p, &s);
			update(p, s);
		}
		else {
			scanf("%d", &s);
			printf("%d\n", query(s));
		}
	}

/*	for (i = 1; i <= 10; i++)
		cout<< bs[2][i]<<" ";*/

	return 0;
}