Cod sursa(job #3230518)

Utilizator Ilie_MityIlie Dumitru Ilie_Mity Data 21 mai 2024 20:25:28
Problema Arbore Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.98 kb
// Ilie "The-Winner" Dumitru
#include<cstdio>
#include<set>
#include<vector>
const int NMAX = 100005, BLKSZ = 300;

int N;
std::vector<int> G[NMAX];
int first[NMAX], last[NMAX], curr;

void dfs(int node, int tt = -1)
{
	int i;

	first[node] = curr++;
	for(i = 0;i < (int)G[node].size();++i)
		if(G[node][i] != tt)
			dfs(G[node][i], node);
	last[node] = curr - 1;
}

int v[NMAX];
std::set<int> where[NMAX * 10];
int blockAdd[NMAX / BLKSZ + 5];

int blockId(int i)
{
	return i / BLKSZ;
}

void add(int node, int sum)
{
	int start = first[node], end = last[node];
	int startId = blockId(start), endId = blockId(end);
	int i;

	if(startId == endId)
	{
		for(i = start;i <= end;++i)
		{
			where[v[i]].erase(i);
			v[i] += sum;
			where[v[i]].insert(i);
		}
	}
	else
	{
		for(i = start;blockId(i) == startId;++i)
		{
			where[v[i]].erase(i);
			v[i] += sum;
			where[v[i]].insert(i);
		}
		for(i = end;blockId(i) == endId;--i)
		{
			where[v[i]].erase(i);
			v[i] += sum;
			where[v[i]].insert(i);
		}
		for(i = startId + 1;i < endId;++i)
			blockAdd[i] += sum;
	}
}

int find(int sum)
{
	int i, blk, x;
	std::set<int>::iterator it;

	for(blk = i = 0;i < N;i += BLKSZ, ++blk)
	{
		x = sum - blockAdd[blk];
		if(x > -1)
		{
			it = where[x].lower_bound(i);
			if(it != where[x].end() && *it < i + BLKSZ)
				return *it + 1;
		}
	}

	return -1;
}

int main()
{
	FILE* f = fopen("arbore.in", "r"), *g = fopen("arbore.out", "w");
//	FILE* f = stdin, *g = stdout;
	int _, i, a, b, op, node, sum;

	fscanf(f, "%d%d", &N, &_);
	where[0].insert(0);
	for(i = 1;i < N;++i)
	{
		where[0].insert(i);
		fscanf(f, "%d%d", &a, &b);
		G[--a].push_back(--b);
		G[b].push_back(a);
	}

	dfs(0);

	do
	{
		fscanf(f, "%d", &op);
		if(op == 1)
		{
			fscanf(f, "%d%d", &node, &sum);
			add(node - 1, sum);
		}
		else
		{
			fscanf(f, "%d", &sum);
			fprintf(g, "%d\n", find(sum));
		}
	}while(--_);

	fclose(f);
	fclose(g);
	return 0;
}