Cod sursa(job #3240373)

Utilizator Ilie_MityIlie Dumitru Ilie_Mity Data 14 august 2024 15:18:34
Problema Heapuri cu reuniune Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.51 kb
#include<iostream>
#include<vector>
#include<algorithm>

std::vector<std::vector<std::pair<int, int> > > heaps;
std::vector<std::pair<int, int> > coord;

void init(int N)
{
	heaps.resize(N);
}

void push_up(int i, int j)
{
	std::vector<std::pair<int, int> >& heap=heaps[i];
	int p;

	while(j)
	{
		p=(j-1)/2;
		if(heap[j].first<heap[p].first)
		{
			std::swap(heap[j], heap[p]);
			std::swap(coord[heap[j].second].second, coord[heap[p].second].second);
			j=p;
		}
		else
			break;
	}
}

void add(int i, int x)
{
	int j=(int)heaps[i].size();
	heaps[i].emplace_back(x, (int)coord.size());
	coord.emplace_back(i, j);

	push_up(i, j);
}

void push_down(int i, int j)
{
	std::vector<std::pair<int, int> >& heap=heaps[i];
	int p, s0, s1, N=(int)heap.size();

	for(p=j;;)
	{
		s0=(p<<1)|1;
		s1=s0+1;

		if(s0>=N)
			break;

		if(s1<N)
		{
			if(heap[s1].first<heap[s0].first)
			{
				if(heap[s1].first<heap[p].first)
				{
					std::swap(heap[s1], heap[p]);
					std::swap(coord[heap[s1].second].second, coord[heap[p].second].second);
					p=s1;
				}
				else
					break;
			}
			else if(heap[s0].first<heap[p].first)
			{
				std::swap(heap[s0], heap[p]);
				std::swap(coord[heap[s0].second].second, coord[heap[p].second].second);
				p=s0;
			}
			else
				break;
		}
		else if(heap[s0].first<heap[p].first)
		{
			std::swap(heap[s0], heap[p]);
			std::swap(coord[heap[s0].second].second, coord[heap[p].second].second);
			p=s0;
		}
		else
			break;
	}
}

int get_min(int i)
{
	int x=heaps[i][0].first;

	heaps[i][0]=heaps[i].back();
	coord[heaps[i][0].second].second=0;
	heaps[i].pop_back();

	push_down(i, 0);

	return x;
}

void decrease_key(int i, int x)
{
	int j=coord[i].second;
	i=coord[i].first;

	heaps[i][j].first-=x;
	push_up(i, j);
}

void merge_sets(int i, int j)
{
	int k, N=(int)heaps[i].size(), M=(int)heaps[j].size();

	for(k=0;k<M;++k)
	{
		heaps[i].emplace_back(heaps[j][k]);
		coord[heaps[j][k].second].first=i;
		coord[heaps[j][k].second].second=N+k;
	}
	heaps[j].clear();

	for(j=(N+M-2)/2;j>-1;--j)
		push_down(i, j);
}

int main()
{
	freopen("mergeheap.in", "r", stdin);
	freopen("mergeheap.out", "w", stdout);
	//std::ios_base::sync_with_stdio(false);
	//std::cin.tie(0);

	int N, _, op, i, j, x;

	std::cin>>N>>_;

	init(N);

	do
	{
		std::cin>>op>>i;
		--i;
		switch(op)
		{
		case 1:
			std::cin>>x;
			add(i, -x);
			break;
		case 2:
			std::cout<<-get_min(i)<<'\n';
			break;
		/*case 3:
			std::cin>>x;
			decrease_key(i, x);
			break;*/
		case 3:
			std::cin>>j;
			--j;
			merge_sets(i, j);
			break;
		}
	}while(_-=1);

	return 0;
}