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

时间:2023-03-09 03:31:00
hdu 2852  KiKi's K-Number  (线段树)

版权声明:本文为博主原创文章,未经博主允许不得转载。

hdu 2852

题意:

  一个容器,三种操作:

    (1) 加入一个数 e

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

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

解法:

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

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

code:线段树

 #include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <map>
#define ll long long using namespace std; const int N=1e5+; int L[N*],R[N*],cnt[N*]; inline void bulidtree(int l,int r,int k){
L[k]=l; R[k]=r;
cnt[k]=;
if (l==r) return;
int mid=(l+r)>>;
bulidtree(l,mid,k<<);
bulidtree(mid+,r,(k<<)|);
} inline void update(int p,int d,int k){
cnt[k]+=d;
if (L[k]==R[k]) return;
int mid=(L[k]+R[k])>>;
if (p<=mid) update(p,d,k<<);
else update(p,d,(k<<)|);
} inline int query(int x,int y,int k){
if (L[k]==x && R[k]==y)
return cnt[k];
int mid=(L[k]+R[k])>>;
if (y<=mid) return query(x,y,k<<);
else if (x>mid) return query(x,y,(k<<)|);
else return query(x,mid,k<<)+query(mid+,y,(k<<)|);
} inline int find(int x,int k){
if (cnt[k]<x) return -;
while (L[k]!=R[k]){
if (x<=cnt[k<<]) k=k<<;
else {
x-=cnt[k<<];
k=(k<<)|;
}
}
return L[k];
} int main(){
int m;
while (~scanf("%d",&m)){
int p,x,y;
bulidtree(,N-,);
while (m--){
scanf("%d",&p);
switch(p){
case :
scanf("%d",&x);
update(x,,);
break;
case :
scanf("%d",&x);
if (query(x,x,)) update(x,-,);
else puts("No Elment!");
break;
case :
scanf("%d%d",&x,&y);
int ans=find(query(,x,)+y,);
if (~ans) printf("%d\n",ans);
else puts("Not Find!");
break;
}
}
}
return ;
}