题目链接:D. Shop
题目大意:洛谷
题解:三种操作,先考虑顺序。操作 1 最先,2 其次,3 最末,证明显然。然后如果进行操作 1,那么肯定对于任意一个数只操作 1 次,并且一定赋为最大值,这也显而易见,所以我们可以将赋值操作转换为加法操作。
对于同一个数的加法操作总是从大向小加肯定不劣,所以我们将同一个数的加法从大往小排序,这样的话每一次加法可以转换为当前数乘上一个浮点数,这样的话就转换为了操作 3。
现在我们只有操作 3 了,从大向小排序,贪心取即可,最后将 1,2,3操作的顺序调换一下就可以了。时间复杂度(O(nlog n))。
代码:。
#include <vector>
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
void read(int &a){
a=0;
char c=getchar();
while(c<'0'||c>'9'){
c=getchar();
}
while(c>='0'&&c<='9'){
a=(a<<1)+(a<<3)+(c^48);
c=getchar();
}
}
typedef long long ll;
const int Maxn=100000;
int a[Maxn+5];
int k,n,m;
int op[Maxn+5];
vector<pair<int,int> > q[Maxn+5][3];
int id[Maxn+5],len;
vector<pair<double,int> > b;
bool cmp(int p,int q){
if(op[p]==op[q]){
return p<q;
}
return op[p]<op[q];
}
int main(){
read(k),read(n),read(m);
for(int i=1;i<=k;i++){
read(a[i]);
}
for(int i=1;i<=n;i++){
read(op[i]);
int pos,x;
read(pos),read(x);
q[pos][op[i]-1].push_back(make_pair(x,i));
}
for(int i=1;i<=k;i++){
if(!q[i][0].empty()){
sort(q[i][0].begin(),q[i][0].end());
if(q[i][0].back().first>a[i]){
q[i][1].push_back(make_pair(q[i][0].back().first-a[i],q[i][0].back().second));
}
}
if(!q[i][1].empty()){
sort(q[i][1].begin(),q[i][1].end(),greater<pair<int,int> >());
ll sum=a[i];
for(int j=0;j<(int)q[i][1].size();j++){
b.push_back(make_pair(1.0*(sum+q[i][1][j].first)/sum,q[i][1][j].second));
sum+=q[i][1][j].first;
}
}
if(!q[i][2].empty()){
for(int j=0;j<(int)q[i][2].size();j++){
b.push_back(make_pair(1.0*q[i][2][j].first,q[i][2][j].second));
}
}
}
sort(b.begin(),b.end(),greater<pair<double,int> >());
for(int i=0;i<m&&i<(int)b.size();i++){
id[++len]=b[i].second;
}
sort(id+1,id+1+len,cmp);
printf("%d
",len);
for(int i=1;i<=len;i++){
printf("%d ",id[i]);
}
puts("");
return 0;
}