码迷,mamicode.com
首页 > 其他好文 > 详细

hdu5171(矩阵快速幂)

时间:2015-02-07 22:50:24      阅读:231      评论:0      收藏:0      [点我收藏+]

标签:

 

传送门: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\n",(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

 

hdu5171(矩阵快速幂)

标签:

原文地址:http://www.cnblogs.com/lienus/p/4279363.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!