您的位置:首页 > 其它

HDOJ 2852 KiKi's K-Number(树状数组)

2012-08-11 23:23 417 查看
超级传送门:http://acm.hdu.edu.cn/showproblem.php?pid=2852

题意:有一个容器里有m个数(1<=m<100000),可以加入新的数,也可以删掉已有的数。有多次查询,查询容器中第k大的数(非递减序列的第k个元素)。

分析:用树状数组来维护这个容器,每次查找用二分。

代码:

#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 100010;
int c[maxn];
int n;
int lowbit(int t) {
return t & -t;
}
int getsum(int end) {
int ret=0;
for (int i=end;i>=1;i-=lowbit(i)) {
ret += c[i];
}
return ret;
}
void update(int p,int val) {
for (int i=p;i<maxn;i+=lowbit(i)) {
c[i] += val;
}
}
void query(int a,int k) {
int l = a+1;
int r = maxn-1;
int res,mid,ans=-1;
k += getsum(a);
while (l<=r) {
mid = (l+r)/2;
res = getsum(mid);
if (res>=k) {
r = mid-1;
ans = mid;
} else {
l = mid+1;
}
}
if (ans==-1) printf("Not Find!\n");
else printf("%d\n",ans);
return;
}
int main () {
#ifndef ONLINE_JUDGE
freopen("1.txt","r",stdin);
#endif
int cmd,e,a,k;
while (scanf("%d",&n)>0) {
memset(c,0,sizeof(c));
for (int i=1;i<=n;i++) {
scanf("%d",&cmd);
if (cmd==0) {
scanf("%d",&e);
update(e,1);
} else if (cmd==1) {
scanf("%d",&e);
if (getsum(e)-getsum(e-1)==0) printf("No Elment!\n");
else update(e,-1);
} else if (cmd==2) {
scanf("%d%d",&a,&k);
query(a,k);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: