http://acm.xmu.edu.cn/JudgeOnline/problem.php?id=1165

树状数组+二分写的

代码
#include <iostream>
#include 
<cstdio>
#include 
<cstring>

using namespace std;
const int MAXN = 100000+10;


int c[MAXN];
bool a[MAXN];
bool flag;
int lowbit(int x)
{
    
return x &(-x);
}

void update(int x,int v)
{
    
while(x<MAXN)
    {
        c[x]
+=v;
        x
+=lowbit(x);
    }
}
int getSum(int x)
{
    
int sum = 0;
    
while(x>0)
    {
        sum
+=c[x];
        x
-=lowbit(x);
    }
    
return sum;
}
int cal(int k,int l,int r)
{
    
if(k>getSum(r))
    {
        
return -1;
    }
    
while(l<r)
    {
        
int mid = (l+r)>>1;
        
int t = getSum(mid);
        
int tt = getSum(mid-1);
        
if(t>=k&&tt<k)
          
return mid;
        
if(t>=k)
        {
            r 
= mid-1;
        }
        
else
        {
            l 
= mid+1;
        }
    }
    
return r;
}
int main()
{
    memset(c,
0,sizeof(c));
    memset(a,
false,sizeof(a));
    
int n;
    scanf(
"%d",&n);
    
for(int i=0;i<n;i++)
    {
        
int cmd,x;
        scanf(
"%d%d",&cmd,&x);
        
if(cmd==1)
        {
            
if(!a[x])
            {
              update(x,
1);
              a[x] 
= true;
            }
        }
        
else if(cmd==2)
        {
            
if(a[x])
            {
               update(x,
-1);
               a[x] 
= false;
            }
        }
        
else
        {
            
int ans = cal(x,1,MAXN-1);
            printf(
"%d\n",ans);
        }
    }
    
return 0;
}