第十五屆中北大學算法與程序設計競賽(公開賽)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

我們發現用集合按上述步驟模擬對第三步是不好求的,那麼我們不妨反向思考,用集合 SS 存上述步驟所得集合 PP 的補集,即所有步驟反過來,如果向 PP 中添加,則從 SS 中刪除;如果刪除,則向 SS 中添加。我們初始化存入所有待操作數 xxx+1x+1 即可,對第三步查找,只需在集合 SS 中使用 lower_boundlower\_bound 即可,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]));
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章