zoukankan      html  css  js  c++  java
  • hdu5171(矩阵快速幂)

    传送门:GTY's birthday gift

    题意:GTY的朋友ZZF的生日要来了,GTY问他的基友送什么礼物比较好,他的一个基友说送一个可重集吧!于是GTY找到了一个可重集S,GTY能使用神犇魔法k次,每次可以向可重集中加入一个数 a+b(a,bS),现在GTY想最大化可重集的和,这个工作就交给你了。 注:可重集是指可以包含多个相同元素的集合

    分析:想要和最大,那么每次必定从集合里面拿出最大的两个出来相加,然后k次后面就类似斐波那契数列了。

    由斐波那契数列公式知:Fn=Fn-1+Fn-2,求和公式有Sn=Sn-1+Fn.因此用这两个公式构造矩阵,进行矩阵快速幂。

            Sn-1    | 1 1 0|   Sn

            Fn   * | 0 1 1| =Fn+1

            Fn-1    | 0 1 0|   Fn

    然后ans=(Sn+(sum-a[n-1]-a[n-2]))%mod(sum为原集合总和,然后减去最大的两个,加上k次后的序列之和(即斐波那契数列和))。

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <cstdlib>
    #include <stack>
    #include <vector>
    #include <set>
    #include <map>
    #define LL long long
    #define mod 10000007
    #define inf 0x3f3f3f3f
    #define N 40010
    #define clr(a) (memset(a,0,sizeof(a)))
    using namespace std;
    struct matrix
    {
        LL m[3][3];
    };
    LL a[100010];
    matrix mult(matrix a,matrix b)
    {
        matrix c;
        memset(c.m,0,sizeof(c.m));
        for(int i=0;i<3;i++)
        for(int j=0;j<3;j++)
        {
            if(a.m[i][j]==0)continue;
            for(int k=0;k<3;k++)
            {
                if(b.m[j][k]==0)continue;
                c.m[i][k]+=a.m[i][j]*b.m[j][k]%mod;
                c.m[i][k]%=mod;
            }
        }
        return c;
    }
    matrix quickmod(matrix a,int n)
    {
        matrix temp;
        memset(temp.m,0,sizeof(temp.m));
        for(int i=0;i<=2;i++)temp.m[i][i]=1;
        while(n)
        {
            if(n&1)temp=mult(temp,a);
            a=mult(a,a);
            n/=2;
        }
        return temp;
    }
    int main()
    {
        LL n,k;
        while(scanf("%I64d%I64d",&n,&k)>0)
        {
            LL sum=0;
            for(int i=0;i<n;i++)scanf("%I64d",&a[i]),sum+=a[i];
            sort(a,a+n);
            matrix ans;
            ans.m[0][0]=1;ans.m[0][1]=1;ans.m[0][2]=0;
            ans.m[1][0]=0;ans.m[1][1]=1;ans.m[1][2]=1;
            ans.m[2][0]=0;ans.m[2][1]=1;ans.m[2][2]=0;
            ans=quickmod(ans,k+1);
            printf("%I64d
    ",(1LL*ans.m[0][0]*a[n-2]+1LL*ans.m[0][1]*a[n-1]+1LL*ans.m[0][2]*a[n-2]+sum-(a[n-1]+a[n-2]))%mod);
        }
    }
    View Code
  • 相关阅读:
    java常用集合总结
    java集合类——Stack栈类与Queue队列
    Snmp的学习总结(一)
    Java中StringBuilder的清空方法比较
    String,StringBuffer与StringBuilder
    浅谈Oracle数据库分区表
    关于java读取文件IO流学习总结(一)
    关于java读取文件IO流学习总结(二)
    CSS
    Datatables 配置
  • 原文地址:https://www.cnblogs.com/lienus/p/4279363.html
Copyright © 2011-2022 走看看