题目:http://acm.hdu.edu.cn/showproblem.php?pid=4006
分析:查询第k大,其中一做法是二分+树状数组,复杂度是log^2(n),还有一种是树状数组logn。
代码:
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <map>
using namespace std;
const int Tmax=1000005;
struct node{
int x,op;
};
node data[Tmax];
int n,m,ls[Tmax],last,C[Tmax],p[Tmax];
map<int,int> mp;
void add(int x)
{
for(;x<=n;x+=x&-x)
C[x]++;
return;
}
int find(int k)
{
int i,ans=0,cnt=0;
for(i=20;i>=0;i--)
{
ans+=(1<<i);
if(ans>=n||cnt+C[ans]>=k)
ans-=(1<<i);
else cnt+=C[ans];
}
return ans+1;
}
int main()
{
int i,k;
char ch;
while(scanf("%d%d",&m,&k)==2)
{
mp.clear();
last=0;
memset(C,0,sizeof(C));
for(i=1;i<=m;i++)
{
getchar();
scanf("%c",&ch);
if(ch=='I') {
scanf("%d",&data[i].x);
data[i].op=1;
ls[++last]=data[i].x;
}
else data[i].op=2;
}
sort(ls+1,ls+1+last);
n=unique(ls+1,ls+1+last)-ls-1;
for(i=1;i<=n;i++)
{
mp[ls[i]]=i;
p[i]=ls[i];
}
last=0;
for(i=1;i<=m;i++)
{
if(data[i].op==1) add(mp[data[i].x]),last++;
else {
printf("%d\n",p[find(last-k+1)]); //第k大,第last-k+1小
}
}
}
return 0;
}