• BZOJ4547: Hdu5171 小奇的集合


    【传送门:BZOJ4547


    简要题意:

      给有一个大小为n的可重集S,每次操作可以加入一个数a+b(a,b均属于S),求k次操作后它可获得的S的和的最大值。(数据保证这个值为非负数)


    题解:

      我们先来看看,因为我们要得到最大的S,所以每次我们都要使得a+b最大

      首先排除一开始得到的a,b为负数的情况,我们将a+b放进S里,那么下一次操作就会将a+(a+b)(假设a>b)放进S里,再下一次就会将(a+b)+(a+b+a)放进S里,这样子就相当于一个斐波那契数列,我们就可以用矩阵乘法来求值

      但是数据保证和的最大值为非负数,就说明a一定为正数,有可能b为负数

      那么我们就暴力操作直到将b变为非负数即可

      WA了半版,发现原来不能用负数来取mod,要+mod数再取mod,气死我了


    参考代码:

    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    typedef long long LL;
    int Mod=10000007;
    struct node
    {
        LL a[4][4];
        node()
        {
            memset(a,0,sizeof(a));
        }
    }d,cmd;
    node chengfa(node a,node b)
    {
        node c;
        for(int i=1;i<=3;i++)
        {
            for(int j=1;j<=3;j++)
            {
                for(int k=1;k<=3;k++)
                {
                    c.a[i][j]=(c.a[i][j]+a.a[i][k]*b.a[k][j])%Mod;
                }
            }
        }
        return c;
    }
    node p_mod(node a,int b)
    {
        node ans;
        ans.a[1][1]=1;ans.a[2][2]=1;ans.a[3][3]=1;
        while(b!=0)
        {
            if(b%2==1) ans=chengfa(ans,a);
            a=chengfa(a,a);
            b/=2;
        }
        return ans;
    }
    LL a[110000];
    int main()
    {
        LL n,k;
        scanf("%lld%lld",&n,&k);
        LL sum=0;
        LL max1=-1<<31,max2=-1<<31;
        for(int i=1;i<=n;i++)
        {
            scanf("%lld",&a[i]);
            sum=(sum+a[i]+Mod)%Mod;
            if(a[i]>max1)
            {
                max2=max1;
                max1=a[i];
            }
            else if(a[i]>max2) max2=a[i];
        }
        if(k==0){printf("%lld
    ",sum);return 0;}
        while(max2<0)
        {
            max2=max2+max1;
            sum=(sum+max2)%Mod;
            k--;if(k==0){printf("%lld
    ",sum);return 0;}
        }
        d.a[1][1]=max1;d.a[1][2]=max2;d.a[1][3]=sum;
        cmd.a[1][1]=1;cmd.a[2][1]=1;
        cmd.a[1][2]=1;
        cmd.a[1][3]=1;cmd.a[2][3]=1;cmd.a[3][3]=1;
        d=chengfa(d,p_mod(cmd,k));
        printf("%lld
    ",d.a[1][3]);
        return 0;
    }

     

  • 相关阅读:
    Spring IOC
    C++ 内存模型
    C++ 多态
    Java 多态
    Java 自动装箱与自动拆箱
    C++ priority_queue
    多个页面使用到一些名称类的同一个接口,借助vuex实现
    element-ui自定义表单验证
    vue项目中导出excel文件
    数组对象根据某个属性进行排序
  • 原文地址:https://www.cnblogs.com/Never-mind/p/8562540.html
Copyright © 2020-2023  润新知