您的位置:首页 > 编程语言 > Go语言

hdu 2852 树状数组查询元素位置

2014-07-14 14:01 417 查看
利用树状数组本身也和二分相类似

关键是找出比所需元素个数少1的下表 然后再把下标+1就可以了 

不能直接找元素个数等于所求值的下表 因为树状数组是上区间包含了下区间的

所以会找到上区间的下标

#include<stdio.h>
#include<iostream>
#include<cstdio>
using namespace std;
#define maxn 222222
int c[maxn];
int lb(int x){return x&(-x);}

int sum(int x){
int ans=0;
while(x){
ans+=c[x];
x-=lb(x);
}
return ans;
}

void add(int x,int w){
while(x<maxn){
c[x]+=w;
x+=lb(x);
}
}

int get_index(int x){
int cur=0,ans=0;
for(int i=20;i>=0;i--){
ans+=(1<<i);
if(ans>=maxn||cur+c[ans]>=x)ans-=(1<<i);
else if(cur+c[ans]<x)cur+=c[ans];
}
return ans+1;
}
int main(){
int n;
while(~scanf("%d",&n)){
memset(c,0,sizeof c);

int op,a,b;
while(n--){
scanf("%d",&op);
if(op==0){
scanf("%d",&a);
add(a,1);

}
else if(op==1){
scanf("%d",&a);
int tmp=sum(a)-sum(a-1);
if(tmp==0)printf("No Elment!\n");
else add(a,-1);
}
else if(op==2){
scanf("%d%d",&a,&b);
int tmp=sum(maxn-1)-sum(a);

if(tmp<b){printf("Not Find!\n");}
else printf("%d\n",get_index(sum(a)+b));
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  algorithm