[CF521D]Shop
[CF521D]Shop
题目大意:
你有一个长度为\(k(k\le10^5)\)的数列\(A_{1\sim k}\),有\(n(n\le10^5)\)种操作,操作包含以下\(3\)种:
- 将\(A_x\)变成\(y\);
- 将\(A_x\)加上\(y\);
- 将\(A_x\)乘以\(y\)。
定义这个数列的收益为各项之积,你可以从中选\(m\)个操作(每个操作至多选\(1\)次),使得收益最大,求任一操作的方案。
思路:
贪心,对于只有操作\(3\)的情况,显然从大到小贪心更优。
而操作\(2\)可以转化成操作\(3\),操作\(1\)又可以转化成操作\(2\),因此最后还是可以用同样的方式贪心。
源代码:
#include<queue>
#include<cstdio>
#include<cctype>
#include<vector>
#include<algorithm>
#include<functional>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'0';
while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
return x;
}
typedef long long int64;
const int N=1e5+1;
int ans[N];
std::pair<int,int> b[N];
struct Modify {
int a,b,c;
bool operator > (const Modify &rhs) const {
return c>rhs.c;
}
};
Modify q[N];
std::vector<std::pair<int,int> > v[N];
struct Node {
int id;
double c;
bool operator < (const Node &rhs) const {
return c<rhs.c;
}
};
std::priority_queue<Node> h;
inline bool cmp(const int &i,const int &j) {
return q[i].a<q[j].a;
}
int main() {
const int k=getint(),n=getint(),m=getint();
for(register int i=1;i<=k;i++) {
v[i].push_back(std::make_pair(getint(),0));
}
for(register int i=1;i<=n;i++) {
q[i].a=getint();
q[i].b=getint();
q[i].c=getint();
if(q[i].a==1) {
b[q[i].b]=std::max(b[q[i].b],std::make_pair(q[i].c-v[q[i].b][0].first,i));
}
if(q[i].a==3) {
h.push((Node){i,1.*q[i].c});
}
}
for(register int i=1;i<=k;i++) {
if(b[i].first>0) v[i].push_back(b[i]);
}
for(register int i=1;i<=n;i++) {
if(q[i].a==2) {
v[q[i].b].push_back(std::make_pair(q[i].c,i));
}
}
for(register int i=1;i<=k;i++) {
std::sort(v[i].begin()+1,v[i].end(),std::greater<std::pair<int,int> >());
int64 sum=v[i][0].first;
for(register unsigned j=1;j<v[i].size();j++) {
h.push((Node){v[i][j].second,1.*(sum+v[i][j].first)/sum});
sum+=v[i][j].first;
}
}
for(register int i=1;!h.empty()&&i<=m;i++) {
ans[++ans[0]]=h.top().id;
h.pop();
}
if(ans[0]==0) {
puts("0");
return 0;
}
std::sort(&ans[1],&ans[ans[0]]+1,cmp);
for(register int i=0;i<=ans[0];i++) {
printf("%d%c",ans[i]," \n"[!(i%ans[0])]);
}
return 0;
}