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 x2 x c3Output
Print the answers for the queries of type
3
in the given order, separated by newlines.Sample 1
Inputcopy Outputcopy 8 1 3 1 2 3 1 2 1 7 3 2 2 3 3 1 5 4The 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
Inputcopy Outputcopy 4 1 10000 1 1000 2 100 3 1 10If 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);
}
}
}