第十五届中北大学算法与程序设计竞赛(公开赛)F.集合操作

第十五届中北大学算法与程序设计竞赛(公开赛)F.集合操作

题目链接

题目描述

有一个集合S,刚开始是空集,现在有3种操作。
1.往集合中添加x,如果集合中已经存在x,则不添加。
2.从集合中删除x,如果集合中不存在x,则不删除。
3.查询大于等于x且不在集合S中的最小的正整数

输入描述:

第一行输入n,表示有n次操作
接下来n行,每行输入两个正整数id和x。
id表示执行的操作序号
1<=n<=1000000,1<=id<=3,1<=x<=1000 000 000

输出描述:

对于每一个操作3,输出一个正整数表示查询到的结果

示例1

输入

5
1 3
1 5
3 3
3 4
3 5

输出

4
4
6

我们发现用集合按上述步骤模拟对第三步是不好求的,那么我们不妨反向思考,用集合 S S S 存上述步骤所得集合 P P P 的补集,即所有步骤反过来,如果向 P P P 中添加,则从 S S S 中删除;如果删除,则向 S S S 中添加。我们初始化存入所有待操作数 x x x x + 1 x+1 x+1 即可,对第三步查找,只需在集合 S S S 中使用 l o w e r _ b o u n d lower\_bound lower_bound 即可,AC代码如下:

#include
using namespace std;
typedef long long ll;
const int N=1e6+5;
set<int>s;
int op[N],num[N];
main(){
     
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
     
        scanf("%d%d",&op[i],&num[i]);
        s.insert(num[i]);
        s.insert(num[i]+1);
    }
    for(int i=0;i<n;i++){
     
        if(op[i]==1) s.erase(num[i]);
        else if(op[i]==2) s.insert(num[i]);
        else printf("%d\n",*s.lower_bound(num[i]));
    }
}

你可能感兴趣的:(思维,牛客,set)