Cod sursa(job #999293)

Utilizator alex_unixPetenchea Alexandru alex_unix Data 19 septembrie 2013 20:21:52
Problema Arbore Scor 100
Compilator cpp Status done
Runda Lista lui wefgef Marime 2.43 kb

#include <fstream>
#include <vector>
#include <bitset>
#include <utility>
#include <cmath>

typedef std::pair<int,int> Bucket;

const int MAX_N(100005);
const int MAX_BUCKET(320);
const int MAX_VALUE(1000001);

int n, m, Size;
std::vector<int> Graph [MAX_N];
std::bitset<MAX_VALUE> Mark [MAX_BUCKET];
Bucket v [MAX_BUCKET];
int Tree [MAX_N], Pos;
std::pair<int,int> Index [MAX_N];
int Add [MAX_BUCKET];
int Value [MAX_N];
bool Viz [MAX_N];

void TreeDecomposition (int node)
{
	++Pos;
	Viz[node] = true;
	Tree[Pos] = node;
	Index[node].first = Pos;
	for (auto it : Graph[node])
		if (!Viz[it])
			TreeDecomposition(it);
	Index[node].second = Pos;
}

void Build (void)
{
	int root(std::sqrt(n));
	int i(1), j(root);
	while (true)
	{
		++Size;
		v[Size].first = i;
		v[Size].second = j;
		Mark[Size][0] = true;
		if (j == n)
			break;
		i = j + 1;
		j = std::min(j + root,n);
	}
}

void Update (int left, int right, int value)
{
	for (int i(1), j, end ; i <= Size ; ++i)
	{
		if (v[i].second < left)
			continue;
		if (v[i].first > right)
			break;
		if (left <= v[i].first && v[i].second <= right)
			Add[i] += value;
		else
		{
			for (j = v[i].first, end = v[i].second ; j <= end ; ++j)
			{
				Mark[i][Value[j]] = false;
				Value[j] += Add[i] + (left <= j && j <= right ? value : 0);
			}
			Add[i] = 0;
			for (j = v[i].first, end = v[i].second ; j <= end ; ++j)
				Mark[i][Value[j]] = true;
		}
	}
}

int Query (int value)
{
	for (int i(1), j, end ; i <= Size ; ++i)
		if (Add[i] <= value && Mark[i][value - Add[i]])
		{
			for (j = v[i].first, end = v[i].second ; j <= end ; ++j)
				if (Value[j] + Add[i] == value)
					return Tree[j];
		}
	return -1;
}

inline int Number (char *s)
{
	int result(0);
	static int i;
	for (i = 0 ; s[i] ; ++i)
		result = result * 10 + s[i] - '0';
	return result;
}

int main (void)
{
	std::ifstream input("arbore.in");
	std::ofstream output("arbore.out");
	char s [100];
	input >> s;
	n = Number(s);
	input >> s;
	m = Number(s);
	for (int i(1), x, y ; i < n ; ++i)
	{
		input >> s;
		x = Number(s);
		input >> s;
		y = Number(s);
		Graph[x].push_back(y);
		Graph[y].push_back(x);
	}
	TreeDecomposition(1);
	Build();
	int t, x, y;
	while (m)
	{
		input >> s;
		t = Number(s);
		if (t == 1)
		{
			input >> s;
			x = Number(s);
			input >> s;
			y = Number(s);
			Update(Index[x].first,Index[x].second,y);
		}
		else
		{
			input >> s;
			x = Number(s);
			output << Query(x) << '\n';
		}
		--m;
	}
	input.close();
	output.close();
	return 0;
}