题目描述
有 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;
struct node
{
int amo,num;
};
vector<node>v;
bool cmp(node x,node y)
{
return x.num>y.num;
}
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
int a;
cin>>a;
v.push_back({1,a});
}
for(int i=1;i<=m;i++)
{
int b,c;
cin>>b>>c;
v.push_back({b,c});
}
sort(v.begin(),v.end(),cmp);
long long sum=0;
int q=0;
for(int i=1;i<=n;i++)
{
sum+=v[q].num;
v[q].amo--;
if(v[q].amo==0)
q++;
}
cout<<sum;
return 0;
}
---------------------------------------------------------------------------------------------------------------------------------
整数卡片:
这道题我前面写的时候问题不大,结果后面写着写着发现超时了,我爸爸说是因为遍历map的时候没有erase。
但是erase之后又RTE了,因为在用AUTO遍历的时候,是不能修改的,会影响红黑树的结构。
所以我开了一个vector,把要erase的下标都存了进去,最后再一块儿erase就好了。这种方法叫“在线算法”。
又是整数卡片:
老师评论了“整数卡片”之后,我用老师的方法又写了一编,果然方便多了。这种方法叫“离线算法”。