hdu 2852 KiKi's K-Number (线段树)

hdu 2852

题意:

  一个容器,三种操作:

    (1) 加入一个数 e

    (2) 删除一个数 e,如果不存在则输出 No Elment! 

    (3) 查询比a大的数中的第k小数,不存在就输出 Not Find!

解法:

  关于第三点,可以先查询小于等于a的数的个数cnt,然后直接查询第cnt+k小数就行了 。

  二分+树状数组 或者 主席树(有点杀鸡用牛刀的感觉 。。。) 也是可以做的  _(:з」∠)_

code:线段树

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cmath>
 5 #include <cstring>
 6 #include <queue>
 7 #include <set>
 8 #include <vector>
 9 #include <map>
10 #define ll long long
11 
12 using namespace std;
13 
14 const int N=1e5+7;
15 
16 int L[N*4],R[N*4],cnt[N*4];
17 
18 inline void bulidtree(int l,int r,int k){
19     L[k]=l; R[k]=r;
20     cnt[k]=0;
21     if (l==r) return;
22     int mid=(l+r)>>1;
23     bulidtree(l,mid,k<<1);
24     bulidtree(mid+1,r,(k<<1)|1);
25 }
26 
27 inline void update(int p,int d,int k){
28     cnt[k]+=d;
29     if (L[k]==R[k]) return;
30     int mid=(L[k]+R[k])>>1;
31     if (p<=mid) update(p,d,k<<1);
32     else update(p,d,(k<<1)|1);
33 }
34 
35 inline int query(int x,int y,int k){
36     if (L[k]==x && R[k]==y)
37         return cnt[k];
38     int mid=(L[k]+R[k])>>1;
39     if (y<=mid) return query(x,y,k<<1);
40     else if (x>mid) return query(x,y,(k<<1)|1);
41     else return query(x,mid,k<<1)+query(mid+1,y,(k<<1)|1);
42 }
43 
44 inline int find(int x,int k){
45     if (cnt[k]<x) return -1;
46     while (L[k]!=R[k]){
47         if (x<=cnt[k<<1]) k=k<<1;
48         else {
49             x-=cnt[k<<1];
50             k=(k<<1)|1;
51         }
52     }
53     return L[k];
54 }
55 
56 int main(){
57     int m;
58     while (~scanf("%d",&m)){
59         int p,x,y;
60         bulidtree(1,N-7,1);
61         while (m--){
62             scanf("%d",&p);
63             switch(p){
64                 case 0:
65                     scanf("%d",&x);
66                     update(x,1,1);
67                     break;
68                 case 1:
69                     scanf("%d",&x);
70                     if (query(x,x,1)) update(x,-1,1);
71                     else puts("No Elment!");
72                     break;
73                 case 2:
74                     scanf("%d%d",&x,&y);
75                     int ans=find(query(1,x,1)+y,1);
76                     if (~ans) printf("%d
",ans);
77                     else puts("Not Find!");
78                     break;
79             }
80         }
81     }
82     return 0;
83 }
原文地址:https://www.cnblogs.com/without-ACM/p/5935063.html