jzoj2292-PPMM【模拟,堆】

正题

题目链接:https://jzoj.net/senior/#contest/show/3008/0


题目大意

一个队列要求支持

  1. 队尾压入一个数
  2. 队首弹出一个数
  3. 队列里所有数取反
  4. 求最大值

解题思路

4 4 个堆,存正数最大值最小值,负数最大值最小值,取反时打标记即可。


c o d e code

#pragma GCC optimize(2)
%:pragma GCC optimize(3)
%:pragma GCC optimize("Ofast")
%:pragma GCC optimize("inline")
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
struct node{
	int pos,val;
};
bool operator<(node x,node y)
{return x.val<y.val;}
struct node2{
	int pos,val;
};
bool operator<(node2 x,node2 y)
{return x.val>y.val;}
priority_queue<node> q1,q2;
priority_queue<node2> p1,p2;
int T,z,zero,tail,head,q[2010000];
int main()
{
	scanf("%d",&T);
	z=0;head=1;
	while(T--){
		char op[8];int x;
		scanf("%s",op);
		if(op[1]=='U'){
			scanf("%d",&x);
			if(!x) zero++,q[++tail]=0;
			else if((x>0)^z) q[++tail]=1,q1.push((node){tail,abs(x)}),p1.push((node2){tail,abs(x)});
			else if((x<0)^z) q[++tail]=-1,q2.push((node){tail,abs(x)}),p2.push((node2){tail,abs(x)});;
		}
		if(head>tail) continue;
		if(op[1]=='O'){
			if(!q[head]) zero--;
			head++;
		}
		if(op[1]=='I') z^=1;
		if(op[1]=='A'){
			while(!q1.empty()&&q1.top().pos<head) q1.pop();
			while(!q2.empty()&&q2.top().pos<head) q2.pop();
			while(!p1.empty()&&p1.top().pos<head) p1.pop();
			while(!p2.empty()&&p2.top().pos<head) p2.pop();
			if(!z){
				if(!q1.empty()) printf("%d\n",q1.top().val);
				else if(zero) printf("0\n");
				else if(!p2.empty()) printf("%d\n",-p2.top().val);
			}
			else{
				if(!q2.empty()) printf("%d\n",q2.top().val);
				else if(zero) printf("0\n");
				else if(!p1.empty()) printf("%d\n",-p1.top().val);
			}
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Mr_wuyongcong/article/details/104196670