Link:
http://www.sdutacm.org/sdutoj/problem.php?action=showproblem&problemid=3252
Lowest Unique Price
Time Limit: 1000ms Memory limit:65536K
题目描述
Recently mybuddies and I came across an idea! We want to build a website to sell things ina new way.
For each product, everyone could bid at a price, orcancel his previous bid, finally we sale the product to the one who offered the
"lowest unique price". The lowest unique price is defined to be thelowest price that was called only once.
So we need aprogram to find the "lowest unique price", We'd like to write aprogram to process the customers' bids and answer the
query of what's thecurrent lowest unique price.
All what we neednow is merely a programmer. We will give you an "Accepted" as long asyou help us to write the program.
输入
The first line ofinput contains an integer T, indicating the number of test cases (T ≤ 60).
Each test case begins with a integer N (1 ≤ N ≤ 200000)indicating the number of operations.
Next N lines each represents an operation.
There are three kinds of operations:
"b x": x(1 ≤ x ≤ 106) is an integer, this means a customer bids at price x.
"c x": acustomer has canceled his bid at price x.
"q" :means "Query". You should print the current lowest unique price.
Our customers arehonest, they won\'t cancel the price they didn't bid at.
输出
Please print the current lowest unique price forevery query ("q"). Print "none" (without quotes) if thereis no lowest unique price.
示例输入
2
3
b 2
b 2
q
12
b 2
b 2
b 3
b 3
q
b 4
q
c 4
c 3
q
c 2
q
示例输出
none
none
4
3
2
提示
这个题的大意是,有很多顾客投标和取消投标,每次查询给出不重复的投标的最小值。
比如投标有(1,1,2,2,3,4,4,5),那么查询之后就显示3,如果进行取消比如取消一个2,那么投标有(1,1,2,3,4,4,5),那么查询之后
就是2,如果再增加2,3,5那么就没有不重复的最小值,那么就显示”none”.这样我们想到利用STL里面的priority_queue进行一定的修改。
代码
#include <cstdio>
#include <queue>
#include <cstring>
#include <iostream>
using namespace std;
const int maxx(1e6+10);/****所有可能出现的投标值得最大值***/
int now[maxx];/***标记某个值在pq这个优先队列中的个数***/
int _minus[maxx];/***标记某个在pq这个优先队列中,还要取消的次数***/
priority_queue <int > pq;
priority_queue <int > tmp;
void init()/***仅作初始化***/
{
memset(now,0,sizeof(now));
memset(_minus,0,sizeof(_minus));
while(!pq.empty())
pq.pop();
while(!tmp.empty())
tmp.pop();
}
void query()
{
int _now;
while(!pq.empty())
{
_now=pq.top();
if(_minus[-_now]>0)/****如果还有要进行取消,那么就把他弹出去,并且这一定不是求的点****/
{
now[-_now]--;
_minus[-_now]--;
pq.pop();
}
else
{
if(now[_now]==1)/****如果在队列中只有一个,并且不需要取消,那么这必然是要求的点****/
{
cout<<-_now<<endl;
break;
}
else
{
tmp.push(_now);/****此时证明要求的点如果存在的话,应该在当前值的后面,把当前值弹出,
然后存在tmp这个优先队列中****/
pq.pop();
}
}
}
if(pq.empty())/***如果已经弹空了还是没有找到,则证明不存在***/
{
puts("none");
}
while(!tmp.empty())/****把存在优先队列里的节点全部弹回pq这个优先队列******/
{
_now=tmp.top();
tmp.pop();
pq.push(_now);
}
}
int main()
{
int t;
scanf("%d",&t);
char cmd;
int a;
while(t--)
{
int n;
scanf("%d",&n);
init();
while(n--)
{
scanf(" %c",&cmd);
switch(cmd)
{
case 'b':/****投标时,把这个数放入优先队列pq,在优先队列pq中的个数++****/
scanf("%d",&a);
now[a]++;
pq.push(-a);/****因为优先队列是从大到小排的,每次摘出来的都是最大的,因此我们取一个相反数****/
break;
case 'c':
scanf("%d",&a);
_minus[a]++;/****记录要取消还没有取消的次数****/
break;
default :
query();
break;
}
}
}
return 0;
}
/**************************************
Problem id : SDUT OJ 3252
User name : crawl
Result : Accepted
Take Memory : 8540K
Take Time : 720MS
Submit Time : 2016-05-26 20:13:46
**************************************/