萌新对顶堆求调
  • 板块P1801 黑匣子
  • 楼主BLX32M_10
  • 当前回复11
  • 已保存回复11
  • 发布时间2023/6/15 16:36
  • 上次更新2023/10/23 13:06:30
查看原帖
萌新对顶堆求调
529247
BLX32M_10楼主2023/6/15 16:36
#include <cstdio> //sr duiding = di i xiao
int sr[400005], mr[400005], ss, ms, i, a[200005], u[200005];
int swap(int &x, int &y)
{
	int temp = x;
	x = y;
	y = temp;
}
void sadd(int x) // 小根堆添加 
{
	sr[++ss] = x;
	int now = ss;
	while (now / 2 && sr[now / 2] > sr[now])
	{
		swap(sr[now], sr[now / 2]);
		now /= 2;
	}
}
void madd(int x) // 大根堆添加
{
	mr[++ms] = x;
	int now = ms;
	while (now / 2 && mr[now / 2] < mr[now])
	{
		swap(mr[now], mr[now / 2]);
		now /= 2;
	}
}
void spop() // 小根堆删除 
{
	swap(sr[1], sr[ss]);
	ss--;
	int now = 1;
	while (now * 2 <= ss)
	{
		int x = now * 2;
		if (x + 1 <= ss && sr[x] > sr[x + 1])
			x++;
		if (sr[x] < sr[now])
		{
			swap(sr[x], sr[now]);
			now = x;
		}
		else
			break;
	}
}
void mpop()  // 大根堆删除
{
	swap(mr[1], mr[ms]);
	ms--;
	int now = 1;
	while (now * 2 <= ms)
	{
		int x = now * 2;
		if (x + 1 <= ms && mr[x] < mr[x + 1])
			x++;
		if (mr[x] > mr[now])
		{
			swap(mr[x], mr[now]);
			now = x;
		}
		else
			break;
	}
}
void mt() // 维护对顶堆 
{
	while (ss < i && ms > 0)
	{
		sadd(mr[1]);
		mpop();
	}
	while (ss > i)
	{
		madd(sr[1]);
		spop();
	}
}
void add(int x) // 向对顶堆添加一个数 
{
	if (x >= sr[1])
		sadd(x);
	else
		madd(x);
	mt();
}
int main()
{
	int m, n, now = 0;
	scanf("%d %d", &m, &n);
	for (int j = 1; j <= m; j++)
		scanf("%d", &a[j]);
	for (int j = 0; j < n; j++)
		scanf("%d", &u[j]);
	for (int j = 1; j <= m; j++)
	{
		add(a[j]);
		while (u[now] == j)
		{
			i++;
			mt();
			printf("%d\n", sr[1]);
			now++;
		}
	}
	return 0;
}
2023/6/15 16:36
加载中...