Cod sursa(job #1261943)

Utilizator iordache.bogdanIordache Ioan-Bogdan iordache.bogdan Data 12 noiembrie 2014 21:06:34
Problema Arbore Scor 100
Compilator cpp Status done
Runda Lista lui wefgef Marime 1.84 kb
#include <fstream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <bitset>
#define DIM 100005
#define SQRT 400
#define vint vector<int>::iterator
#define infile "arbore.in"
#define outfile "arbore.out"

using namespace std;

ifstream f(infile);
ofstream g(outfile);

vector<int> L[DIM];

bitset<DIM * 10> OK[SQRT];

int Start[DIM], Finish[DIM];

int Nod[DIM], A[DIM], ADD[SQRT];

int n, q, nod, S, op, x, y, nr, rad;

void DFS(int nod) {
	++nr;
	Start[nod] = nr;
	Nod[nr] = nod;
	for (vint it = L[nod].begin(); it != L[nod].end(); ++it)
		if (Start[*it] == -1)
			DFS(*it);
	Finish[nod] = nr;
}

void update(int st, int dr) {
	for (int i = st / rad; i <= dr / rad; ++i) {
		if (i * rad >= st && (i + 1) * rad - 1 <= dr) {
			ADD[i] += S;
			continue;
		}
		if (st <= (i + 1) * rad - 1 || dr >= i * rad) {
			int p = i * rad, u = (i + 1) * rad - 1;
			p = std::max(p, st);
			u = std::min(u, dr);
			for (int j = i * rad; j <= (i + 1) * rad - 1 && j < n; ++j)
				OK[i][A[j]] = 0;
			for (int j = i * rad; j <= (i + 1) * rad - 1 && j < n; ++j) {
				A[j] += ADD[i];
				if (j >= p && j <= u)
					A[j] += S;
				OK[i][A[j]] = 1;
			}
			ADD[i] = 0;
		}
	}
}

int query() {
	for (int i = 0; i < rad; ++i)
		if (S - ADD[i] >= 0 && OK[i][S - ADD[i]])
			for (int j = i * rad; j <= (i + 1) * rad - 1 && j < n; ++j)
				if (A[j] + ADD[i] == S)
					return Nod[j];
	return -1;
}

int main() {
	f >> n >> q;
	for (int i = 1; i < n; ++i) {
		f >> x >> y;
		L[x].push_back(y);
		L[y].push_back(x);
	}
	rad = sqrt(n);
	++rad;
	nr = -1;
	for (int i = 1; i <= n; ++i)
		Start[i] = -1;
	DFS(1);
	for (; q; --q) {
		f >> op;
		if (op == 1) {
			f >> nod >> S;
			update(Start[nod], Finish[nod]);
			continue;
		}
		f >> S;
		g << query() << "\n";
	}
	return 0;
}

//Trust me, I'm the Doctor!