第十五屆中北大學算法與程序設計競賽(公開賽)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
我們發現用集合按上述步驟模擬對第三步是不好求的,那麼我們不妨反向思考,用集合 存上述步驟所得集合 的補集,即所有步驟反過來,如果向 中添加,則從 中刪除;如果刪除,則向 中添加。我們初始化存入所有待操作數 和 即可,對第三步查找,只需在集合 中使用 即可,AC代碼如下:
#include<bits/stdc++.h>
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]));
}
}