PPMM【JZOJ】

DescriptionDescription

實現一個隊列,完成以下四個操作
PUSH X:將整數X加入到隊尾。
POP:將隊首的數字出隊。
MINUS:隊列中所有數字都變爲其相反數,即X —> -X。
MAX:返回隊列中最大的數。
如果隊列爲空,POP,MINUS,MAX操作可忽略

InputInput

輸入第一行爲正整數N,表示操作的個數。
接下來N行,每行爲一個操作。所有操作都用大寫字母表示。PUSH操作後會接着一個正整數X。

OutputOutput

對於每個沒有被忽略的MAX操作,輸出其返回的數字,每個數字各佔一行。

SampleSample InputInput

6
PUSH -2
MINUS
PUSH -1
MAX
POP
MAX

SampleSample OutputOutput

 2
-1

HintHint

-2^31 < X < 2^31
對於20%的數據有 N ≤ 100
對於50%的數據有N ≤ 10,000
對於100%的數據有N ≤ 2,000,000

TrainTrain ofof ThoughtThought

先來兩個堆
分別記錄隊列裏的數與其相反數
然後當有數需出隊時
再來兩個堆
將其數加進這兩個堆中
(其中一個裝相反數)
然後當MAX時
先一個while處理相對應的兩個堆的堆頂是否相等
因爲當相等時
就表示這個數早已出隊
然後將這個數從堆中踢出
記得用一個數組當隊列
否則無法確定出隊的是哪一個數

#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
priority_queue<int>A, A_, B, B_;
int T, k, l, r;
int F[2000250];
char s[10];
int flag;
int read() 
{
	int x = 0,flag = 1;char c = getchar();
	while(c < '0' || c>'9'){if(c == '-')flag = -1;c = getchar();}
	while(c >= '0' && c <= '9'){x = x * 10 + c - '0', c = getchar();}
	return x * flag;
}
void write(int x)
{
    if(x < 0){x = -x;putchar('-');}
	if(x > 9)write(x / 10);
	putchar(x % 10 + 48);
	return;
}
int main()
{
	T = read();
	flag = 0, l = 1;
	for(register int t = 1; t <= T; ++t)
	{
		scanf("%s", s);
		if(s[1] == 'U') 
		{
			F[++r] = read();
			if(flag)F[r] = -F[r];
			A.push(F[r]);
			A_.push(-F[r]);
		}
		else if(s[1] == 'O' && l <= r) 
		{
			B.push(F[l]);
			B_.push(-F[l]);
			l++;
		}
		else if(s[1] == 'I')flag = (flag + 1) % 2;
		else if(s[1] == 'A' && l <= r)
		{
			if(!flag)
			{
				while(A.size() && B.size() && A.top() == B.top())
					A.pop(), B.pop();
				write(A.top());
				putchar('\n');
			}
			else
			{
				while(A_.size() && B_.size() && A_.top() == B_.top())
					A_.pop(), B_.pop();
				write(A_.top());
				putchar('\n');
			}
		}
	}
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章