贪心
先分析一下性质
-
每个位置的赋值操作至多做一次
-
每个位置先加后乘,赋值和加法都可以化为乘法
加法和乘法一定按b排序,于是加法内部顺序是固定的
所以可以排序后算出每次相当于乘多少,然后将所有操作按 b 再排序取前 m 个
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+11;
struct opt_{
int ty,x,sum;
int num;
double xl;
}cf[N];
int n,k,m,sl;
int a[N];
int maxx[N],num[N];
vector<opt_> vct[N];
inline int read()
{
int s=0;
char ch=getchar();
while(ch>'9'||ch<'0') ch=getchar();
while(ch>='0'&&ch<='9')
{
s=(s<<1)+(s<<3)+(ch^48);
ch=getchar();
}
return s;
}
bool cmpxl(opt_ a,opt_ b){return a.xl>b.xl;}
bool cmps(opt_ a,opt_ b){return a.sum>b.sum;}
bool cmpx(opt_ a,opt_ b){return a.x!=b.x?a.x<b.x:a.ty<b.ty;}
signed main()
{
n=read();
m=read();
k=read();
for(int i=1;i<=n;++i) a[i]=read();
for(int ty,x,y,i=1;i<=m;++i)
{
ty=read();
x=read();
y=read();
if(ty==1){if(maxx[x]<y){maxx[x]=y;num[x]=i;}}
else if(ty==2) vct[x].push_back((opt_){2,x,y,i});
else cf[++sl]=(opt_){3,x,y,i,(double)y};
}
for(int i=1;i<=n;++i)
{
if(maxx[i]>a[i]) vct[i].push_back((opt_){1,i,maxx[i]-a[i],num[i]});
sort(vct[i].begin(),vct[i].end(),cmps);
if(vct[i].size())
{
int sum=vct[i][0].sum+a[i];
vct[i][0].xl=(double)sum/a[i];
cf[++sl]=vct[i][0];
for(int j=1;j<vct[i].size();++j)
{
vct[i][j].xl=(double)(sum+vct[i][j].sum)/sum;
sum+=vct[i][j].sum;
cf[++sl]=vct[i][j];
}
}
}
sort(cf+1,cf+sl+1,cmpxl);
k=min(sl,k);
sort(cf+1,cf+k+1,cmpx);
cout<<k<<endl;
for(int i=1;i<=k;++i) printf("%lld ",cf[i].num);
return 0;
}