题目:luogu1801.
这道题就是说,维护一个序列的两种操作:
1.插入一个数.
2.k+1之后查询这串序列的第i小.
注:开始k为0.
所以这道题是如何用堆来维护的呢?
我们可以维护两个堆,一个大根堆和一个小根堆,初始时都为空,然后我们把大根堆作为序列比第k个数小的那一段,吧小根堆作为另一段.
那么我们就可以维护这道题了,在操作1时将这个数与大根堆的堆顶比较,若插入的书更大,则插入到后面的小根堆中,否则将大根堆堆顶弹出插入到小根堆中,再将输入的数插入大根堆中.
操作2时直接把小根堆堆顶弹出就可以了.
那么代码如下:
#include<bits/stdc++.h> using namespace std; #define TLE priority_queue int n,m,a[200001],b[200001]; void into(){ scanf("%d%d",&m,&n); for (int i=1;i<=m;i++) scanf("%d",&a[i]); for (int i=1;i<=n;i++) scanf("%d",&b[i]); sort(b+1,b+1+n); } TLE<int>maxq; TLE<int,vector<int>,greater<int> >minq; int main(){ into(); int k=1,j=1; for (int i=1;i<=m;i++){ if (k==1||maxq.top()<=a[i]) minq.push(a[i]); else {minq.push(maxq.top());maxq.pop();maxq.push(a[i]);} while (b[j]==i){ printf("%d\n",minq.top()); maxq.push(minq.top());minq.pop(); j++;k++; } } return 0; }
这是早期作品,具体是怎么样的本人也不记得了,但是思路就是这样的,可能有一些细节上的问题.