题目描述
有 N 张卡片,第 i 张卡上写着整数 Ai。
你接下来将要进行 M 次操作:
第 𝑗j 次操作有两个参数 Bj 和 Cj,表示这次操作你要
选择最多Bj张卡片(可以选0张),将选出卡片上的整数改成Cj。
M次操作结束后,N张卡片上的整数之和的最大值是多少?
【输入格式】
第1行,2个正整数N,M
第2行,N个正整数A1,A2,⋯,AN
接下来𝑀M行,每行两个正整数𝐵𝑗,𝐶𝑗Bj,Cj
【输出格式】
输出𝑀M次操作后所有卡片上整数总和的最大值
【输入输出样例#1】
输入#1
3 2 5 1 4 2 3 1 5
输出#1
14
【输入输出样例#2】
输入#2
10 3 1 8 5 7 100 4 52 33 13 5 3 10 4 30 1 4
输出#2
338
【输入输出样例#3】
输入#3
11 3 1 1 1 1 1 1 1 1 1 1 1 3 1000000000 4 1000000000 3 1000000000
输出#3
10000000001
【说明提示】
样例#1说明
第1次操作:B1=2,C1=3,可以最多选2张卡改成3。只选择将第2张卡改成3。
第2次操作:B2=1,C2=5,可以最多选1张卡改成5。只选择将第2张卡改成5。
最终所有卡上的数总和为5+5+4=14为最大
样例#2说明
第1次操作:B1=3,C1=10,可以最多选3张卡改成10。选择第1,3,61,3,6张卡改成10,数组变成 [10,8,10,7,100,10,52,33,13,5][10,8,10,7,100,10,52,33,13,5]。
第2次操作:B2=4,C2=30,可以最多选4张卡改成30。选择第1,2,4,101,2,4,10张卡改成30,数组变成 [30,30,10,30,100,10,52,33,13,30][30,30,10,30,100,10,52,33,13,30]。
第3次操作:B3=1,C3=4,可以最多选1张卡改成4。这次不选择任何卡,数组不变。
最终所有卡上的数总和为 338
【数据范围】
1≤N≤105
1≤M≤105
1≤Ai,Cj≤109
1≤Bj≤N
---------------------------------------------------------------------------------------------------------------------------------
#include <bits/stdc++.h>
using namespace std;
map<int,int>mp;
int main()
{
int n,m;
cin>>n>>m;
long long sum=0;
for(int i=1;i<=n;i++)
{
int a;
cin>>a;
mp[a]++;
sum+=a;
}
while(m--)
{
int b,c;
cin>>b>>c;
int i=0;
vector<int> ee;
for(auto &it:mp)
{
if(i==b||it.first>=c)
break;
int num=it.second;
if(b-i<=num)
{
mp[c]+=b-i;
it.second-=b-i;
sum+=1ll*(b-i)*(c-it.first);
if( it.second==0)
ee.push_back(it.first);
break;
}
it.second-=num;
i+=num;
mp[c]+=num;
sum+=1ll*num*(c-it.first);
ee.push_back(it.first);
}
for(auto k:ee)
mp.erase(k);
}
cout<<sum;
return 0;
}
---------------------------------------------------------------------------------------------------------------------------------
这道题我前面写的时候问题不大,结果后面写着写着发现超时了,我爸爸说是因为遍历map的时候没有erase。
但是erase之后又RTE了,因为在用AUTO遍历的时候,是不能修改的,会影响红黑树的结构。
所以我开了一个vector,把要erase的下标都存了进去,最后再一块儿erase就好了。