Cod sursa(job #348746)

Utilizator katakunaCazacu Alexandru katakuna Data 16 septembrie 2009 19:03:21
Problema Arbore Scor 15
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.1 kb
#include <cstdio>
#include <vector>
#include <math.h>
using namespace std;

#define Nmax 100010

int n, m, x, y, i, tip, p, s, rad, l, strad, drrad;
int viz[Nmax], nr[Nmax], poz[Nmax], v[Nmax], a[Nmax], b[350], P[350][1000];
vector <int> V[Nmax];

void DFS (int nod) {

	v[++v[0]] = nod; poz[nod] = v[0]; viz[nod] = 1; nr[nod] = 1;
	int i;
	for (i = 0; i < (int)V[nod].size(); i++)
		if ( !viz[ V[nod][i] ] ) {
			DFS (V[nod][i]);
			nr[nod]+= nr[ V[nod][i] ];
		}

}

void update (int p, int s) {
	
	int irad, st = poz[p], dr = st + nr[p] - 1, NR = rad;
	
	for (irad = 1; st > NR ; irad++, NR+= rad);
	strad = irad;
	
	for (irad = irad, NR = irad * rad; dr > NR ; irad++, NR+= rad);
	drrad = irad;
	
	if (strad == drrad)
		for (i = st; i <= dr; i++){
			P[strad][a[i]]--;
			a[i]+= s;
			P[strad][a[i]]++;
		}
	
	else {
		l = strad * rad;
		for (i = st; i <= l; i++) {
			P[strad][a[i]]--;
			a[i]+= s;
			P[strad][a[i]]++;
		}
		
		for (irad = strad + 1; irad <= drrad - 1; irad++)
			b[irad]+= s;
		
		l = (drrad - 1) * rad + 1;
		for (i = l; i <= dr; i++) {
			P[drrad][a[i]]--;
			a[i]+= s;
			P[drrad][a[i]]++;
		}
	}
	
}

int query (int s) {
	
	int irad, i;
	for (irad = 1; irad <= rad + 1; irad++)
		if ( s - b[irad] > 0 && P[irad][ s - b[irad] ] ) {
			l = irad * rad;
			for (i = (irad-1) * rad + 1; i <= l; i++)
				if (a[i] == s - b[irad])
					return v[i];
		}
	
	return -1;
}

int main () {
	
	FILE *f = fopen ("arbore.in", "r");
	FILE *g = fopen ("arbore.out", "w");

	fscanf (f, "%d %d", &n, &m);
	for (i = 1; i < n; i++) {
		fscanf (f, "%d %d", &x, &y);
		V[x].push_back (y);
		V[y].push_back (x);
	}
	
	DFS(1);
	rad = (int)sqrt((double) n);
	
	int irad, NR = rad;
	for (irad = 1; n > NR; irad++, NR+= rad)
		P[irad][0] = rad;
	
	for (i = (irad-1)*rad + 1; i <= n; i++)
		P[irad][0]++;
	
	for (i = 1; i <= m; i++ ){
		fscanf (f, "%d", &tip);
		
		if (tip == 1) {fscanf (f, "%d %d", &p, &s); update(p, s); }
		else {fscanf (f, "%d", &s); fprintf (g, "%d\n", query(s)); }
		
	}
	
	fclose (f);
	fclose (g);
	
	return 0;

}