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

HDU 5171 GTY's birthday gift (矩阵快速幂)

时间:2015-02-08 09:08:51      阅读:274      评论:0      收藏:0      [点我收藏+]

标签:hdu   bestcode   矩阵运算   

题目链接:HDU 5171 GTY‘s birthday gift

题意:每次将序列中两个数相加再加入序列中,反复操作k次,问k次操作后的序列和最大是多少。

思路:序列和最大,显然是每次取序列中最大的两个数相加。

3 2

6 3 2

第一步:6 + 3 = 9 

1 * 6 + 1 * 3 = 9

第二步:6 + 3 + 6 = 15

2 * 6 + 1 * 3 = 15

第三步:6 + 3 + 6 + 6 +3 + 6 = 24

3 * 6 + 2 * 3 = 24

第四步:6 + 3 + 6 + 6 +3 + 6 + 6 + 3 + 6 = 39

5 * 6 + 3 * 3 = 39

........

发现每次6和3前面的系数序列是斐波那契序列,加上k很大,想到矩阵快速幂

构造矩阵:


技术分享


AC代码:


#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll __int64
const ll kmod=10000007;
struct Matrix {
    ll m[10][10];
};
struct Matrix I,s;
ll n;
ll aa[100010];

bool cmp(int a,int b) {
    return a>b;
}

Matrix Mul(Matrix a,Matrix b) {
    Matrix c;
    ll i,j,k;
    for(i=0; i<2; i++) {
        for(j=0; j<2; j++) {
            c.m[i][j]=0;
            for(k=0; k<2; k++) {
                c.m[i][j]+=(a.m[i][k]*b.m[k][j]);
                c.m[i][j]%=kmod;
            }
        }
    }
    return c;
}
Matrix Quickpow(Matrix a,ll n) {
    Matrix m,b;
    m=a,b=I;
    while(n) {
        if(n%2)
            b=Mul(b,m);
        n/=2;
        m=Mul(m,m);
    }
    return b;
}
int main() {
    ll i,j;
    ll k,a,b,sn,sum;
    while(scanf("%I64d %I64d",&n,&k)!=EOF) {
        Matrix ans,p,q;
        memset(I.m,0,sizeof I.m);
        memset(p.m,0,sizeof p.m);
        memset(q.m,0,sizeof q.m);
        sum=0;
        for(i=0; i<n; i++) {
            scanf("%I64d",&aa[i]);
            sum+=aa[i];
            sum%=kmod;
        }
        sort(aa,aa+n,cmp);
        for(i=0; i<2; i++)
            I.m[i][i]=1;
        q.m[0][0]=2;//f2
        q.m[0][1]=1;//f1
        q.m[1][0]=0;
        q.m[1][1]=0;

        p.m[0][0]=1;
        p.m[0][1]=1;
        p.m[1][0]=1;
        p.m[1][1]=0;
        if(k==1) {
            sn=aa[0]+aa[1]+sum;
        } else if(k==2) {
            sn=3*aa[0]+2*aa[1]+sum;
        } else {
            ll tmp;
            ans=Quickpow(p,k-2);
            ans=Mul(q,ans);
            sn=ans.m[0][0]*2+ans.m[0][1]-1-1;
            tmp=sn*aa[0];
            tmp%=kmod;

            ans=Quickpow(p,k-3);
            ans=Mul(q,ans);
            sn=ans.m[0][0]*2+ans.m[0][1]-1;
            tmp+=sn*aa[1]+sum;
        }
        printf("%I64d\n",tmp%kmod);
    }

    return 0;
}




HDU 5171 GTY's birthday gift (矩阵快速幂)

标签:hdu   bestcode   矩阵运算   

原文地址:http://blog.csdn.net/u012377575/article/details/43611699

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