Max - Min Query(set)

Problem Statement

We have a multiset of integers SS, which is initially empty.

Given QQ queries, process them in order. Each query is of one of the following types.

  • 1 x: Insert an xx into SS.

  • 2 x c: Remove an xx from SS mm times, where m = \mathrm{min}(c,(m=min(c,( the number of xx's contained in S))S)).

  • 3 : Print (( maximum value of S)-(S)−( minimum value of S)S). It is guaranteed that SS is not empty when this query is given.

Constraints

  • 1 \leq Q \leq 2\times 10^51≤Q≤2×105
  • 0 \leq x \leq 10^90≤x≤109
  • 1 \leq c \leq Q1≤c≤Q
  • When a query of type 3 is given, SS is not empty.
  • All values in input are integers.

Input

Input is given from Standard Input in the following format:

Q
query1​
⋮
queryQ​

\mathrm{query}_iqueryi​, which denotes the ii-th query, is in one of the following formats:

1 x
2 x c
3

Output

Print the answers for the queries of type 3 in the given order, separated by newlines.

Sample 1

InputcopyOutputcopy
8
1 3
1 2
3
1 2
1 7
3
2 2 3
3
1
5
4

The multiset SS transitions as follows.

  • 11-st query: insert 33 into SS. SS is now \lbrace 3 \rbrace{3}.
  • 22-nd query: insert 22 into SS. SS is now \lbrace 2, 3 \rbrace{2,3}.
  • 33-rd query: the maximum value of S = \lbrace 2, 3\rbraceS={2,3} is 33 and its minimum value is 22, so print 3-2=13−2=1.
  • 44-th query: insert 22 into SS. SS is now \lbrace 2,2,3 \rbrace{2,2,3}.
  • 55-th query: insert 77 into SS. SS is now \lbrace 2, 2,3, 7\rbrace{2,2,3,7}.
  • 66-th query: the maximum value of S = \lbrace 2,2,3, 7\rbraceS={2,2,3,7} is 77 and its minimum value is 22, so print 7-2=57−2=5.
  • 77-th query: since there are two 22's in SS and \mathrm{min(2,3)} = 2min(2,3)=2, remove 22 from SS twice. SS is now \lbrace 3, 7\rbrace{3,7}.
  • 88-th query: the maximum value of S = \lbrace 3, 7\rbraceS={3,7} is 77 and its minimum value is 33, so print 7-3=47−3=4.

Sample 2

InputcopyOutputcopy
4
1 10000
1 1000
2 100 3
1 10
 

If the given queries do not contain that of type 33, nothing should be printed.

其实这题很简单,我也没想别的方法,就想只用set做,我看他们用map+set做的很快就出来了,唉。下面的注释表现了我曾犯过的错。

#include<iostream>
#include<set>
#include<cmath>
#include<algorithm>
using namespace std;
int main()
{
    int q;
    multiset<int>s;
    scanf("%d", &q);
    for (int i = 1; i <= q; i++)
    {
        int  x, c, n, m;
        scanf("%d", &n);
        if (n == 1)
        {
            scanf("%d", &x);
            s.insert(x);
        }
        if (n == 2)
        {
            scanf("%d %d", &x, &c);
            //int mm = min(c, (int)s.count(x));//s.count()会超时
            while (c--)
            {
                multiset <int> ::iterator it1 = s.find(x);
                if (it1 == s.end())
                    break;
                s.erase(it1);//直接传x会把s中的x全删了
            }
        }
        if(n==3)
        {
            if (!s.empty())
            {
                int nn = *(--s.end()) - *s.begin();//set的最后一位是end()-1
                printf("%d\n", nn);
            }
        }
    }
}

多此一举的set+map 

//set+map
#include<iostream>
#include<map>
#include<set>
using namespace std;
map <int, int> m;
set<int>s;

int main()
{
    int q;
    scanf("%d", &q);
    while (q--)
    {
        int n, x, c;
        scanf("%d", &n);
        if (n == 1)
        {
            scanf("%d", &x);
            s.insert(x);
            m[x]++;
        }
        if (n == 2)
        {
            scanf("%d %d", &x, &c);
            if (c >= m[x])
            {
                m[x] = 0;
                s.erase(x);
            }
            else
                m[x] = max(0,m[x] - c);
        }
        if (n == 3)
        {
            printf("%d\n", *(--s.end()) - *(s.begin()));
        }
    }
}

 map做法

#include<iostream>
#include<map>
#include<set>
using namespace std;
map <int, int> m;

int main()
{
    int q;
    scanf("%d", &q);
    while (q--)
    {
        int n, x, c;
        scanf("%d", &n);
        if (n == 1)
        {
            scanf("%d", &x);
            m[x]++;
        }
        if (n == 2)
        {
            scanf("%d %d", &x, &c);
            if (c >= m[x])
            {
                m[x] = 0;
                m.erase(x);
            }
            else
                m[x] = max(0,m[x] - c);
        }
        if (n == 3)
        {
            printf("%d\n", m.rbegin()->first - m.begin()->first);
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值