HDU - 2852 KiKi's K-Number(树状数组+二分)

题目链接

题意:

给定一个容器,该容器支持的操作有三种:

1、加入一个元素

2、删除一个元素

3、查询 $k th$ 比 $a$ 大的数

思路:

元素的值在1e5之内,可以直接用树状数组记录出现的次数

查询的时候用二分查找第k大的数。

 1 /*
 2 *  Author: windystreet
 3 *  Date  : 2018-08-10 09:05:15
 4 *  Motto : Think twice, code once.
 5 */
 6 #include<bits/stdc++.h>
 7 
 8 using namespace std;
 9 
10 #define X first
11 #define Y second
12 #define eps  1e-5
13 #define gcd __gcd
14 #define pb push_back
15 #define PI acos(-1.0)
16 #define lowbit(x) (x)&(-x)
17 #define bug printf("!!!!!\n");
18 #define mem(x,y) memset(x,y,sizeof(x))
19 
20 typedef long long LL;
21 typedef long double LD;
22 typedef pair<int,int> pii;
23 typedef unsigned long long uLL;
24 
25 const int maxn = 1e5+7;
26 const int INF  = 1<<30;
27 const int mod  = 1e9+7;
28 
29 int tree[maxn];
30 int n,sum;
31 void init(){
32     for(int i=0;i<maxn;i++)
33         tree[i] = 0;
34 }
35 void add(int x,int v){
36     for(int i=x;i<maxn;i+=lowbit(i))
37         tree[i]+=v;
38 }
39 int query(int x){
40     int res = 0;
41     for(int i=x;i;i-=lowbit(i))
42         res += tree[i];
43     return res;
44 }
45 bool check(int x,int y){
46     int k = query(x) - sum;
47     return k>=y;                               // 若当前值 >=y 则记录答案
48 }
49 
50 void solve(){
51     int m,op,x,y;
52     while(~scanf("%d",&m)){
53         init();                                // 多case不忘初始化
54         while(m--){
55                scanf("%d",&op);
56             if(op==0){
57                 scanf("%d",&x);
58                 add(x,1);
59             }else if(op==1){
60                 scanf("%d",&x);
61                 if(query(x)-query(x-1)){
62                     add(x,-1);
63                 }else{
64                     puts("No Elment!");        // 若当前值不存在
65                 }
66             }else{
67                 scanf("%d%d",&x,&y);
68                 sum = query(x);                // 记录 [1,x] 区间内元素的个数 
69                 int L = x, R = maxn-1,ans = -1,mid; 
70                 while(L<=R){
71                     mid = (L + R)>>1;
72                     if(check(mid,y)) ans = mid, R = mid-1;
73                     else L = mid+1;
74                 }
75                 if(ans==-1){
76                     puts("Not Find!");
77                 }else{
78                     printf("%d\n",ans);
79                 }
80             }
81         }
82     }
83     return;
84 }
85 
86 int main()
87 {
88 //    freopen("in.txt","r",stdin);
89 //    freopen("out.txt","w",stdout);
90 //    ios::sync_with_stdio(false);
91     int t = 1;
92     //scanf("%d",&t);
93     while(t--){
94     //    printf("Case %d: ",cas++);
95         solve();
96     }
97     return 0;
98 }

 

posted @ 2018-08-10 13:27  windystreet  阅读(269)  评论(0编辑  收藏  举报