Cod sursa(job #3231449)

Utilizator DobraVictorDobra Victor Ioan DobraVictor Data 26 mai 2024 15:35:36
Problema Arbore Scor 100
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.13 kb
#include <iostream>
#include <fstream>
#include <stdint.h>
#include <math.h>
#include <vector>
#include <bitset>

const int32_t MAX_N = 100000;
const int32_t MAX_N_SQRT = 334;
const int32_t MAX_VAL = 1000000;

struct Interval {
	int32_t start, end;
};

int32_t n, m, nSqrt;
std::vector<int32_t> adj[MAX_N];
Interval intervals[MAX_N];
int32_t nodes[MAX_N];

Interval regs[MAX_N_SQRT]; int32_t regsCount;
int32_t vec[MAX_N], regVals[MAX_N_SQRT];
std::bitset<MAX_VAL + 1> frec[MAX_N_SQRT];

int32_t min(int32_t x, int32_t y) {
	return (x < y) ? x : y;
}
int32_t max(int32_t x, int32_t y) {
	return (x > y) ? x : y;
}
void DFS(int32_t node, int32_t prev) {
	nodes[intervals[node].start] = node;
	intervals[node].end = intervals[node].start + 1;

	for(int32_t next : adj[node]) {
		if(next == prev)
			continue;
		intervals[next].start = intervals[node].end;
		DFS(next, node);
		intervals[node].end = intervals[next].end;
	}
}
void Update(int32_t node, int32_t val) {
	Interval interval = intervals[node];

	int32_t startReg = interval.start / nSqrt + 1;
	int32_t endReg = (interval.end - 1) / nSqrt;

	if(startReg > endReg) {
		for(int32_t i = regs[endReg].start; i != regs[endReg].end; ++i)
			frec[endReg][vec[i]] = 0;
		for(int32_t i = interval.start; i != interval.end; ++i)
			vec[i] += val;
		for(int32_t i = regs[endReg].start; i != regs[endReg].end; ++i)
			frec[endReg][vec[i]] = 1;
	} else {
		for(int32_t i = regs[startReg - 1].start; i != regs[startReg - 1].end; ++i)
			frec[startReg - 1][vec[i]] = 0;
		for(int32_t i = interval.start; i != regs[startReg - 1].end; ++i)
			vec[i] += val;
		for(int32_t i = regs[startReg - 1].start; i != regs[startReg - 1].end; ++i)
			frec[startReg - 1][vec[i]] = 1;
		
		for(int32_t i = startReg; i != endReg; ++i)
			regVals[i] += val;

		for(int32_t i = regs[endReg].start; i != regs[endReg].end; ++i)
			frec[endReg][vec[i]] = 0;
		for(int32_t i = regs[endReg].start; i != interval.end; ++i)
			vec[i] += val;
		for(int32_t i = regs[endReg].start; i != regs[endReg].end; ++i)
			frec[endReg][vec[i]] = 1;
	}
}
int32_t Query(int32_t val) {
	for(int32_t i = 0; i != regsCount; ++i) {
		if(val < regVals[i])
			continue;

		if(frec[i][val - regVals[i]]) {
			for(int32_t j = regs[i].start; j != regs[i].end; ++j) {
				if(vec[j] == val - regVals[i])
					return nodes[j];
			}
		}
	}

	return -2;
}

int main() {
	std::ifstream fin("arbore.in");
	std::ofstream fout("arbore.out");

	fin >> n >> m;
	for(int32_t i = 0; i != n - 1; ++i) {
		int32_t x, y;
		fin >> x >> y;
		--x; --y;
		adj[x].push_back(y);
		adj[y].push_back(x);
	}

	intervals[0].start = 0;
	DFS(0, -1);

	nSqrt = (int32_t)sqrt(n);
	for(int32_t end = 0; end != n;) {
		int32_t start = end;
		end += nSqrt;
		end = min(end, n);

		regs[regsCount] = { start, end };
		frec[regsCount][0] = 1;
		++regsCount;
	}

	while(m--) {
		int32_t op, p, s;
		fin >> op;

		switch(op) {
		case 1:
			fin >> p >> s;
			--p;
			Update(p, s);
			break;
		case 2:
			fin >> s;
			fout << (Query(s) + 1) << '\n';
			break;
		}
	}

	fin.close();
	fout.close();

	return 0;
}