【洛谷P1801】黑匣子

黑匣子

题目链接

看到题解中“维护两个堆”,突然想到了这道题的解法

维护两个堆:大根堆h1, 小根堆h2

大根堆里的是最小的i个值,小根堆里是剩下的值

每Add一个值时

插入到小根堆中,

再比较小根堆的最小值与大根堆的最大值

若h2.top()<h1.top()

将两个元素取出,换一下再放进去

需要Get时

将h2.top()取出,放进h1中,

再输出h1.top()

 

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<queue>
 5 using namespace std;
 6 #define LL long long
 7 #define N 200010
 8 #define INF 1e18
 9 LL m,n;
10 struct Add{
11     LL data;
12     LL get;
13 } a[N];
14 struct cmp{
15     bool operator ()(LL x,LL y){
16         return x>y;
17     }
18 };
19 priority_queue<LL> h1;
20 priority_queue< LL, vector<LL>, cmp > h2;
21 inline LL read(){
22     LL x=0,f=1; char c=getchar();
23     while(c<'0'||c>'9') { if(c=='-') f=-1; c=getchar(); }
24     while('0'<=c&&c<='9') { x=(x<<3)+(x<<1)+c-'0'; c=getchar(); }
25     return x*f;
26 }
27 int main()
28 {
29     scanf("%lld%lld",&m,&n);
30     for(LL i=1;i<=m;i++)
31      a[i].data=read();
32     for(LL i=1;i<=n;i++)
33      a[read()].get++;
34     h1.push(-INF); h2.push(INF);
35     for(LL i=1;i<=m;i++){
36         h2.push(a[i].data);
37         if(h1.top()>h2.top()){
38             LL t1=h1.top(),t2=h2.top();
39             h1.pop(); h2.pop();
40             h1.push(t2); h2.push((t1));
41         }
42         for(LL j=1;j<=a[i].get;j++){
43             LL t2=h2.top();
44             h2.pop();
45             h1.push(t2);
46             printf("%lld\n",h1.top());
47         }
48     }
49     return 0;
50 }

 

posted @ 2018-07-26 15:15  yjk  阅读(164)  评论(0编辑  收藏  举报