题意:给出m个操作,
0:是增加一个数,add(x,1)
1:是删除一个指定的数,这个是看sum(x) - sum(x-1)是否为0,为0的话则不存在,不为0的话,则add(x,-1)
2:是查询比x大的数中第k大的数,
先求出比x小的个数s,假设比x大的数中第k大的数为y,
那么比y小的个数有s+k个
二分y的值来找
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include <cmath> 5 #include<stack> 6 #include<vector> 7 #include<map> 8 #include<set> 9 #include<queue> 10 #include<algorithm> 11 using namespace std; 12 13 typedef long long LL; 14 const int INF = (1<<30)-1; 15 const int mod=1000000007; 16 const int maxn=100005; 17 18 int a[maxn],c[maxn]; 19 int k; 20 21 int lowbit(int x){ return x &(-x);} 22 23 int sum(int x){ 24 int ret=0; 25 while(x>0){ 26 ret+=c[x];x-=lowbit(x); 27 } 28 return ret; 29 } 30 31 void add(int x,int d){ 32 while(x<maxn){ 33 c[x]+=d;x+=lowbit(x); 34 } 35 } 36 37 int solve(int x){ 38 int v=x; 39 int s=sum(x); 40 int kk=k+s; 41 int lb=1,ub=maxn,mid; 42 43 for(int i=1;i<=100;i++){ 44 mid=(lb+ub)/2; 45 if(sum(mid) < kk) lb =mid; 46 else ub = mid; 47 // printf("lb = %d ub = %d mid = %d\n",lb,ub,mid); 48 } 49 return ub; 50 } 51 52 53 int main(){ 54 int m; 55 while(scanf("%d",&m) != EOF){ 56 memset(c,0,sizeof(c)); 57 while(m--){ 58 int cmd; 59 scanf("%d",&cmd); 60 if(cmd == 0){ 61 int x; 62 scanf("%d",&x); 63 add(x,1); 64 } 65 if(cmd == 1){ 66 int x; 67 scanf("%d",&x); 68 if(sum(x) - sum(x-1) == 0) printf("No Elment!\n"); 69 else add(x,-1); 70 } 71 if(cmd == 2){ 72 int x; 73 scanf("%d %d",&x,&k); 74 if(sum(maxn-1) - sum(x) < k) printf("Not Find!\n"); 75 else printf("%d\n",solve(x)); 76 } 77 } 78 } 79 return 0; 80 }
HDU 2852 KiKi's K-Number【 树状数组 二分 】
时间: 2024-10-17 19:20:11