首页 > 代码库 > hdu 2852 KiKi's K-Number (线段树)
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 long11 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\n",ans);77 else puts("Not Find!");78 break;79 }80 }81 }82 return 0;83 }
hdu 2852 KiKi's K-Number (线段树)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。