Cod sursa(job #460331)

Utilizator katakunaCazacu Alexandru katakuna Data 1 iunie 2010 22:55:42
Problema Arbore Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.77 kb
#include <cstdio>
#include <stdlib.h>
#include <ctime>
#include <vector>
#include <math.h>
using namespace std;

#define Nmax 100010
#define biti 30

int n, m, N, rad, nr_rad, ult;
int A[Nmax], Poz[Nmax], Nr[Nmax], viz[Nmax], B[350], C[350][350];
int P[350][1000000 / 30 + 10];
vector <int> V[Nmax];

void citire () {
	
	int i, x, y;
	
	scanf ("%d %d", &n, &m);
	for (i = 1; i < n; i++) {
		scanf ("%d %d", &x, &y);
		V[x].push_back (y); V[y].push_back (x);
	}
}

void dfs (int nod) {
	
	viz[nod] = 1;
	A[++N] = nod; Poz[nod] = N; 
	
	for (vector <int>::iterator it = V[nod].begin (); it != V[nod].end (); it++) 
		if (!viz[*it]) {
			dfs (*it);
			Nr[nod]+= Nr[*it];
		}
	
	Nr[nod]++;
}

void update (int nod, int s) {
	
	int x = Poz[nod], y = x + Nr[nod] - 1, a, b, N, i;
	a = (x - 1) / rad + 1; b = (y - 1) / rad + 1;
	
	if (a == b) {
		N = (y - 1) % rad + 1;
		for (i = (x - 1) % rad + 1; i <= N; i++) {
			if (((P[a][ C[a][i] / biti ])>> (C[a][i] % biti)) == 1)P[a][ C[a][i] / biti ]^= (1 << (C[a][i] % biti));
			C[a][i]+= s;
		}
		
		N = rad;
		if (a == nr_rad) N = ult;
		for (i = 1; i <= N; i++) {
			P[a][C[a][i] / biti]|= (1  << (C[a][i] % biti));
		}
	}	
	
	else {
		N = rad;
		if (a == nr_rad) N = ult;
		for (i = (x - 1) % rad + 1; i <= rad; i++) {
			if (((P[a][ C[a][i] / biti ])>> (C[a][i] % biti)) == 1) P[a][ C[a][i] / biti ]^= (1 << (C[a][i] % biti));
			C[a][i]+= s;
		}
		
		N = rad;
		if (a == nr_rad) N = ult;
		for (i = 1; i <= N; i++) 
			P[a][C[a][i] / biti]|= (1  << (C[a][i] % biti));
		
		N = (y - 1) % rad + 1;
		for (i = 1; i <= N; i++) {
			if (((P[b][ C[b][i] / biti ])>> (C[b][i] % biti)) == 1) P[b][ C[b][i] / biti ]^= (1 << (C[b][i] % biti));
			C[b][i]+= s;
		}
		
		N = rad;
		if (b == nr_rad) N = ult;
		for (i = 1; i <= N; i++) 
			P[b][C[b][i] / biti]|= (1  << (C[b][i] % biti));
		
		for (i = a + 1; i < b; i++)
			B[i]+= s;
	}
}

void query (int s) {
	
	for (int i = 1; i <= nr_rad; i++) {
		if (B[i] <= s && ((P[i][ (s - B[i]) / 30 ] >> ((s - B[i]) % 30))&1) == 1) {
			N = rad;
			if (i == nr_rad) N = ult;
			for (int j = 1; j <= N; j++) {
				if (C[i][j] == s - B[i]) {
					printf ("%d\n", A[(i - 1) * rad + j]);
					return ;
				}
			}
		}
	}
	
	printf ("-1\n");
}

void rezolva () {
	
	int i; rad = (int)sqrt(n);
	
	nr_rad = (n - 1) /  rad + 1;
	ult = rad - nr_rad * rad + N;
	
	for (i = 1; i <= nr_rad; i++)
		P[i][0] = 1;
	
	int tip, x, s;
	for (; m; m--) {
		scanf ("%d", &tip);
		if (tip == 1) {
			scanf ("%d %d", &x, &s);
			update (x, s);
		}
		else {
			scanf ("%d", &s);
			query (s);
		}
	}
}


int main () {

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

	citire ();
	dfs (1);
	rezolva ();
	
	return 0;
}