集合操作(STL&逆向)
如果正向储存当前集合的元素的话,查询时会很麻烦。所以我们反向考虑,我们用一个集合储存集合中每个元素的最小未出现的元素(即x+1)
然后我们需要用一个来标记该元素是否在题意的集合中。
对于操作1,我们只需判断是否出现过,如果没出现过就加到中,在判断是否在集合中出现过,若出现过就删掉。对于操作2,就直接加入到中。
然后对于操作3,如果不在题意集合中就直接输出,否则二分一下集合中的元素即可。
时间复杂度:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+5;
#define mst(a) memset(a,0,sizeof a)
unordered_map<int,bool>mp;
set<int>s;
int main(){
int n,op,x;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d%d",&op,&x);
if(op==1){
mp[x]=1;
if(!mp[x+1]) s.insert(x+1);
if(s.count(x)) s.erase(x);
}
else if(op==2) s.insert(x);
else {
if(!mp[x]) printf("%d\n",x);
else printf("%d\n",*(s.lower_bound(x)));
}
}
return 0;
}