如果,我们有个答案数组存了所有的数,当1操作其实是在这个数组中删去x,而2操作是加上x,而3操作的话就是二分找到第一个大于等于x的数。
但x<1000000000,直接存所有数是不可能的。而想一下,每个x,如果它不在题目的S集合中,那么答案肯定就是x,否则就得看前面有没有往S中添加过x+1。
而添加过x+1的话,就还得看x+2,一直到一个没有操作中出现过的数,而这个数肯定是操作出现过的某个数+1。
所有对于每次操作,我们把x跟x+1添加进我们前面所说的答案数组中,这个数组的也就2*n而已了。
为了方便直接用set来实现这个答案数组即可。因为set操作大概是log的,所以nlogn时间复杂度上也可以。
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
const int man = 2e5+10;
#define IOS ios::sync_with_stdio(0)
#define ull unsigned ll
#define uint unsigned
#define pai pair<int,int>
#define pal pair<ll,ll>
#define IT iterator
#define pb push_back
#define fi first
#define se second
#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);++i)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);--i)
#define endl '\n'
#define ll long long
const ll mod = 1e9+7;
vector<pai>op;
set<int>sp;
int main() {
#ifndef ONLINE_JUDGE
//freopen("in.txt", "r", stdin);
//freopen("out.txt","w",stdout);
#endif
int n;
cin >>n;
for(int i = 1;i <= n;++i){
int op1,va;
scanf("%d%d",&op1,&va);
op.pb({op1,va});
sp.insert(va);
sp.insert(va+1);
}
for(int i = 0;i < op.size();++i){
if(op[i].fi==1){
sp.erase(op[i].se);
}else if(op[i].fi==2){
sp.insert(op[i].se);
}else{
int ans = *sp.lower_bound(op[i].se);
printf("%d\n",ans);
}
}
return 0;
}