【洛谷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 }