题目:http://acm.hdu.edu.cn/showproblem.php?pid=2852
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
No Elment! 6 Not Find! 2 2 4 Not Find!
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn=1e5;
struct node{
int l,r,count;
int mid(){ return (l+r)/2; }
}tree[maxn<<2];
void build(int root,int a,int b){
tree[root].l=a;
tree[root].r=b;
tree[root].count=0;
if(a==b) return ;
int m=tree[root].mid();
build(2*root,a,m);
build(2*root+1,m+1,b);
}
void insert(int root,int a,int b,int number){
if(a==b){
tree[root].count++;
return ;
}
int m=(a+b)/2;
if(number<=m)insert(2*root,a,m,number);
else if(number>m)insert(2*root+1,m+1,b,number);
tree[root].count=tree[2*root].count+tree[2*root+1].count;
}
bool work;
void delet(int root,int a,int b,int number){
if(tree[root].count<1){
work=0;
return ;
}
if(a==b){
tree[root].count--;
return ;
}
int m=(a+b)/2;
if(number<=m)delet(2*root,a,m,number);
else if(number>m)delet(2*root+1,m+1,b,number);
tree[root].count=tree[2*root].count+tree[2*root+1].count;
}
int findres;
void inquiry(int root,int a,int b,int q1,int q2){
if(tree[root].count<1){
printf("Not Find!\n");
return ;
}
if(a==b){
printf("%d\n",a);
return ;
}
int m=(a+b)/2;
if(q1<=m&&q2<=tree[2*root].count)
inquiry(2*root,a,m,q1,q2);
else {
if(q1>=tree[2*root].r)q2=q2-tree[2*root].count;
inquiry(2*root+1,m+1,b,q1,q2);
}
}
int main()
{
//freopen("cin.txt","r",stdin);
int m,p,a,b;
while(cin>>m){
build(1,1,maxn);
while(m--){
scanf("%d",&p);
if(p==0){
scanf("%d",&a);
insert(1,1,maxn,a);
}
else if(p==1){
scanf("%d",&a);
work=1;
delet(1,1,maxn,a);
if(work==0){
printf("No Elment!\n");
}
}
else {
scanf("%d%d",&a,&b);
inquiry(1,1,maxn,a,b);
}
}
}
return 0;
}
我怀疑是操作3的函数写的不严谨把。学习一种新的写法:把统计占用结点sum单独写一个函数,删除和加入全写成update,最后的查找函数在sum正常工作的情况下找到第K大的数。
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn=1e5;
struct node{
int l,r,count;
int mid(){ return (l+r)/2; }
}tree[maxn<<4];
void build(int root,int a,int b){
tree[root].l=a;
tree[root].r=b;
tree[root].count=0;
if(a==b) return ;
int m=tree[root].mid();
build(2*root,a,m);
build(2*root+1,m+1,b);
}
void update(int root,int l,int r,int number,int val){
if(l==r){
tree[root].count+=val;
return ;
}
int m=tree[root].mid();
if(number<=m)update(2*root,l,m,number,val);
else update(2*root+1,m+1,r,number,val);
tree[root].count=tree[2*root].count+tree[2*root+1].count;
}
int sum(int root,int l,int r,int ql,int qr){ // l and r is necessary
if(qr<l||ql>r){
return 0;
}
if(ql<=l&&qr>=r){ //care >= == <=
return tree[root].count;
}
int m=(l+r)/2;
return sum(2*root,l,m,ql,qr)+sum(2*root+1,m+1,r,ql,qr);
}
int findgoal(int root,int l,int r,int number){
if(l==r){
return tree[root].l;
}
int m=(l+r)/2;
if(number>tree[2*root].count){
//if(l==r){
// return tree[root].l;
//}
return findgoal(2*root+1,m+1,r,number-tree[2*root].count);
}
return findgoal(2*root,l,m,number);
}
int main()
{
//freopen("cin.txt","r",stdin);
int m,p,a,b;
while(cin>>m){
build(1,1,maxn);
while(m--){
scanf("%d",&p);
if(p==0){
scanf("%d",&a);
update(1,1,maxn,a,1);
//for(int i=20;i>0;i--)cout<<tree[i].count<<" "; cout<<endl;
}
else if(p==1){
scanf("%d",&a);
if(sum(1,1,maxn,1,a)==sum(1,1,maxn,1,a-1)){
printf("No Elment!\n");
}
else update(1,1,maxn,a,-1);
}
else {
scanf("%d%d",&a,&b);
int goal=sum(1,1,maxn,1,a)+b;
//cout<<"goal: "<<goal<<endl;
int ans=findgoal(1,1,maxn,goal);
//cout<<"ans: "<<ans<<endl;
if(ans==maxn)printf("Not Find!\n");
else printf("%d\n",ans);
}
}
}
return 0;
}