ZR贪心10.2

\(shop\)

题目链接

比较容易想到的是先进行赋值操作,并且每个位置只赋值一次。加法操作肯定是选前几次大的。
如果是同一种操作的话,只要排个序就行,但是有三种操作怎么办呢?
我们可以把它转化成同一种操作。
具体实现:
先把赋值转化成加法操作(加上差值),再把加法操作们转化成乘法操作。
重点来了:
不能直接把赋值操作转化成乘法操作。因为加法操作变成乘法操作时,要用到加之前的值。我们默认从大到小加...
举个例子吧:
有个数3,答案是先把它变成5,再加6。
变成5是乘\(\frac{5}{3}\),加2是乘\(\frac{13}{5}\)
但是如果直接把赋值变成乘的话,就变成乘\(\frac{5}{3}\),乘\(\frac{9}{3}\)
竟然还能过146个点
还有就是一个小错点,因为把赋值变成了加操作,所以\(vector\)里存的不全是加法操作了(还有\(flag\)为1的情况)

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#define LL long long
using namespace std;
const LL N = 100005;
LL n,m,a[N],tot,ans,k;
struct node{
    LL p,data,flag;
}opt[N];
vector<node> v[N];
struct Node{
    LL id,flag;
    double val;
}c[N];
bool cmp(const node &x,const node &y)
{ return x.data>y.data; }
bool cmp1(const Node &x,const Node &y)
{ return x.val>y.val; }
bool cmp2(const Node &x,const Node &y)
{ return x.flag<y.flag; }
int main()
{
    scanf("%lld%lld%lld",&k,&n,&m);
    for(LL i=1;i<=k;i++)
     scanf("%lld",&a[i]);
    LL x,y,z;
    for(LL i=1;i<=n;i++)
    {
        scanf("%lld%lld%lld",&x,&y,&z);
        if(x==1&&z>a[y])
        {
            if(opt[y].data<z)
            {
                opt[y].data=z;
                opt[y].p=i;
                opt[y].flag=x;
            }
        }
        if(x==2&&z>0)
         v[y].push_back((node){i,z,2});
        if(x==3&&z>1)
        {
            c[++tot].id=i;
            c[tot].val=(double)z;
            c[tot].flag=3;
        }
    }
    for(LL i=1;i<=k;i++)
    {
        if(opt[i].data>0)
        {
            v[i].push_back((node){opt[i].p,opt[i].data-a[i],1});
            /*c[++tot].id=opt[i].p;
            c[tot].flag=opt[i].flag;
            c[tot].val=double(opt[i].data)/a[i];*/
        }
        sort(v[i].begin(),v[i].end(),cmp);
        for(LL j=0;j<v[i].size();j++)
        {
            node tmp=v[i][j];
            c[++tot].id=tmp.p;
            c[tot].flag=tmp.flag;
            c[tot].val=(double(a[i]+tmp.data)/a[i]);
            a[i]+=tmp.data;
        }
    }
    sort(c+1,c+tot+1,cmp1);
    ans=min(m,tot);
    sort(c+1,c+ans+1,cmp2);
    printf("%lld\n",ans);
    for(LL i=1;i<=ans;i++)
     printf("%lld ",c[i].id);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/karryW/p/11635895.html