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
  • 相关阅读:
    part11-1 Python图形界面编程(Python GUI库介绍、Tkinter 组件介绍、布局管理器、事件处理)
    part10-3 Python常见模块(正则表达式)
    Cyclic Nacklace HDU
    模拟题 Right turn SCU
    状态DP Doing Homework HDU
    Dp Milking Time POJ
    区间DP Treats for the Cows POJ
    DP Help Jimmy POJ
    Dales and Hills Gym
    Kids and Prizes Gym
  • 原文地址:https://www.cnblogs.com/lienus/p/4279363.html
Copyright © 2011-2022 走看看