KiKi's K-Number
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4847 Accepted Submission(s): 2228
Problem Description
For the k-th number, we all should be very familiar with it. Of course,to kiki it is also simple. Now Kiki meets a very similar problem, kiki wants to design a container, the container is to support the three operations.
Push: Push a given element e to container
Pop: Pop element of a given e from container
Query: Given two elements a and k, query the kth larger number which greater than a in container;
Although Kiki is very intelligent, she can not think of how to do it, can you help her to solve this problem?
Push: Push a given element e to container
Pop: Pop element of a given e from container
Query: Given two elements a and k, query the kth larger number which greater than a in container;
Although Kiki is very intelligent, she can not think of how to do it, can you help her to solve this problem?
Input
Input some groups of test data ,each test data the
first number is an integer m (1 <= m <100000), means that the number of
operation to do. The next m lines, each line will be an integer p at the
beginning, p which has three values:
If p is 0, then there will be an integer e (0 <e <100000), means press element e into Container.
If p is 1, then there will be an integer e (0 <e <100000), indicated that delete the element e from the container
If p is 2, then there will be two integers a and k (0 <a <100000, 0 <k <10000),means the inquiries, the element is greater than a, and the k-th larger number.
If p is 0, then there will be an integer e (0 <e <100000), means press element e into Container.
If p is 1, then there will be an integer e (0 <e <100000), indicated that delete the element e from the container
If p is 2, then there will be two integers a and k (0 <a <100000, 0 <k <10000),means the inquiries, the element is greater than a, and the k-th larger number.
Output
For each deletion, if you want to delete the element
which does not exist, the output "No Elment!". For each query, output the
suitable answers in line .if the number does not exist, the output "Not Find!".
Sample Input
5
0 5
1 2
0 6
2 3 2
2 8 1
7
0 2
0 2
0 4
2 1 1
2 1 2
2 1 3
2 1 4
Sample Output
No Elment!
6
Not Find!
2
2
4
Not Find!
__________________________________________________
题目大意:对一个集合进行n种操作
1>,向集合中增加一个数
2>,删除集合中的一个数
3>,查询集合中第k个比a大的数
解题思路:
用树状数组来解决,num[i]表示小于i的元素有几个,因此对于1和2直接对数组进行修改即可,但是对于3我们可以
采用二分的方法进行查找每次查找看一下sum(mid)-sum(a)与k的关系来进行下一次操作,依此进行即可,小于mid的元素的个数减去
小于a的个数即为大于a的元素的个数,用此值与k进行比较即可
#include<iostream> #include<algorithm> using namespace std; #define maxn (int)1e5+5 #include<cstring> typedef long long ll; int lowbit(int x) { return x&(-x); } ll n,c[maxn],vis[maxn]; //c tong ji he zhi c1 tong ji ge shu void add(ll x,ll num) { while(x<=maxn) { c[x]+=num; x+=x&(-x); } } ll sum(ll x) { ll ans=0; while(x) { ans+=c[x]; x-=x&(-x); } return ans; } ll cal(ll r,ll l) { return sum(r)-sum(l); } int main() { int n; while(~scanf("%d",&n)) { memset(c,0,sizeof(c)); memset(vis,0,sizeof(vis)); while(n--) { int a; scanf("%lld",&a); if(a==0) { int b; scanf("%lld",&b); vis[b]++; add(b,1); } else if(a==1) { int b; scanf("%lld",&b); if(vis[b]==0) { cout<<"No Elment!"<<endl; } else { vis[b]--; add(b,-1); } } else { int a,b; cin>>a>>b; int l=a,r=100000; int mid,ret=-1; while(l<=r) { mid=(l+r)>>1; if(cal(mid,a)>=b) { r=mid-1; ret=mid; } else l=mid+1; } if(ret==-1) cout<<"Not Find!"<<endl; else cout<<ret<<endl; } } } return 0; }