集合操作(STL&逆向)

集合操作(STL&逆向)

传送门

如果正向储存当前集合的元素的话,查询时会很麻烦。所以我们反向考虑,我们用一个集合 S S 储存集合中每个元素的最小未出现的元素(即x+1)
然后我们需要用一个 m a p map 来标记该元素是否在题意的集合中。

对于操作1,我们只需判断 x + 1 x+1 是否出现过,如果没出现过就加到 S S 中,在判断 x x 是否在集合 S S 中出现过,若出现过就删掉。对于操作2,就直接加入到 S S 中。

然后对于操作3,如果不在题意集合中就直接输出,否则二分一下集合 S S 中的元素即可。

时间复杂度: O ( n l o g n ) O(nlogn)

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

猜你喜欢

转载自blog.csdn.net/weixin_45750972/article/details/106318422