Max - Min Query(multiset語法)
阿新 • • 發佈:2022-05-29
題意
我們有一個整數的multiset,記為\(S\)。\(S\)一開始為空。
給定\(Q\)個操作,並按順序處理。總共有\(3\)類操作:
- 為\(S\)插入一個元素\(X\)
- 從\(S\)中刪除\(m\)個\(x\),其中\(m = \min (c, k)\),其中\(c\)給定,\(k\)為\(S\)中\(x\)的個數。
- 輸入\(S\)中的最大值 - 最小值,該操作保證\(S\)非空。
資料範圍
\(1 \leq Q \leq 2 \times 10^5\)
思路
本題考查multiset基礎語法,這裡重點分析第二問。
- erase()操作
如果使用如下程式碼:
S.erase(3);
那麼會將\(S\)中的所有\(3\)全部刪除。那麼如何只刪除一次呢?可以考慮傳入迭代器。即:
S.erase(S.find(3));
- count()操作的複雜度
count()的時間複雜度是\(O(k+\log N)\),其中\(N\)是\(S\)中元素的個數,\(k\)是元素\(x\)的個數。
因此,如果第二個操作使用count(),最壞時間複雜度是\(O(Q^2)\)。因此,不能使用S.count()
為了保證時間複雜度,只能使用S.find()
程式碼
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <set> using namespace std; multiset<int> s; int main() { int Q; scanf("%d", &Q); while(Q --) { int op; scanf("%d", &op); if(op == 1) { int x; scanf("%d", &x); s.insert(x); } else if(op == 2) { int x, c; scanf("%d%d", &x, &c); while(c -- && s.find(x) != s.end()) { s.erase(s.find(x)); } } else { printf("%d\n", *s.rbegin() - (*s.begin())); } } return 0; }