Max - Min Query(multiset语法)

题意

我们有一个整数的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;
}
posted @ 2022-05-29 15:50  pbc的成长之路  阅读(24)  评论(0编辑  收藏  举报