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;
}