http://acm.xmu.edu.cn/JudgeOnline/problem.php?id=1165
题意:有3中操作
1 a将a加入,如果a已经存在忽略该操作
2 a将a删除,如果不存在忽略该操作
3 a查询第a大的数,不存在输出-1
分析:思想和pku2182一样,比2182简单。。。直接线段树或树状数组+二分。。。
其实从这个角度而言,树状数组也可以求最大最小值了。。。呵呵,求最小值就是第1小值嘛。。。
代码:
#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <iostream>
using namespace std;
const int N=100002;
int a[N], sum[N], n;
int query(int i)
{
int tmp = 0;
for( ; i>0; i-=i&(-i))
tmp += sum[i];
return tmp;
}
void update(int i, int v)
{
for( ; i<N; i+=i&(-i))
sum[i] += v;
}
int bs(int t)
{
int l, r, mid;
l=1;
r=N-1;
while(l<=r)
{
mid = (l+r)/2;
if(query(mid)>=t)
r = mid-1;
else
l = mid+1;
}
if(l==N)
return -1;
return l;
}
int main()
{
int i, j, x, y, ans;
//freopen("D.in", "w", stdout);
while(scanf("%d", &n)!=EOF)
{
for(i=0; i<N; i++)
{
sum[i] = 0;
a[i] = 0;
}
while(n--)
{
scanf("%d%d", &x, &y);
if(x==1)
{
if(a[y]==0)
{
update(y, 1);
a[y] = 1;
}
}
else if(x==2)
{
if(a[y]!=0)
{
update(y, -1);
a[y] = 0;
}
}
else
{
ans = bs(y);
printf("%d\n", ans);
}
}
}
return 0;
}