Cod sursa(job #3138761)

Utilizator Ilie_MityIlie Dumitru Ilie_Mity Data 21 iunie 2023 21:57:58
Problema Arbore Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.97 kb
//Ilie Dumitru
#include<cstdio>
#include<vector>
#include<unordered_map>
#include<unordered_set>
const int NMAX=100005;
const int BLKSZ=1;

std::vector<int> G[NMAX];
std::unordered_map<int, std::unordered_set<int> > apBlk[NMAX/BLKSZ+1];
int v[NMAX];
int add[NMAX/BLKSZ+1];
int first[NMAX], last[NMAX];
int curr=-1;
int N;

int blkid(int x)
{
	return x/BLKSZ;
}

inline void pointUpdate(int pos, int inc)
{
	int val=v[pos], id=blkid(pos);
	std::unordered_map<int, std::unordered_set<int> >::iterator it=apBlk[id].find(val);

	it->second.erase(pos);
	if(!it->second.size())
		apBlk[id].erase(it);

	apBlk[id][v[pos]+=inc].insert(pos);
}

inline void rangeUpdate(int pos, int inc)
{
	add[blkid(pos)]+=inc;
}

void update(int start, int end, int inc)
{
	while(blkid(start)==blkid(start-1) && start<=end)
		pointUpdate(start++, inc);
	while(blkid(end)==blkid(end+1) && start<=end)
		pointUpdate(end--, inc);
	while(start<=end)
	{
		rangeUpdate(start, inc);
		start+=BLKSZ;
	}
}

int query(int val)
{
	int i, j;
	std::unordered_map<int, std::unordered_set<int> >::iterator it;

	for(i=j=0;i<N;i+=BLKSZ, ++j)
	{
		it=apBlk[j].find(val-add[j]);
		if(it!=apBlk[j].end())
			return *it->second.begin();
	}

	return -2;
}

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;
}

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

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

	dfs(0);

	do
	{
		fscanf(f, "%d%d", &a, &b);
		if(a==1)
		{
			fscanf(f, "%d", &c);
			--b;
			update(first[b], last[b], c);
		}
		else
			fprintf(g, "%d\n", query(b)+1);
	}while(--_);

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