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

hdu 5171 GTY's birthday gift(数学,矩阵快速幂)

时间:2015-03-02 22:22:23      阅读:210      评论:0      收藏:0      [点我收藏+]

标签:

题意:

开始时集合中有n个数。

现在要进行k次操作。

每次操作:从集合中挑最大的两个数a,b进行相加,得到的数添加进集合中。

以此反复k次。

问最后集合中所有数的和是多少。

(2n100000,1k1000000000)

 

思路:

写出来发现是要求Fibonaci的前n个数的和。

Fibonaci是用矩阵快速幂求的,这个也可以。

[Sn,Fn,Fn-1]=[某个矩阵]*[Sn-1,Fn-1,Fn-2]

[S2,F2,F1]=[2,1,1]

然后写,,,

这个代码有些繁琐,应该把矩阵操作单独写成函数。

日后更新。

 

代码:

ll const mol = 10000007;


int n,k;
ll ans;
ll matrix[4][4];
int a[100005];


void matrixSolve(int k){ // ¾ØÕóµÄk´Î·½
    if(k==0){
        mem(matrix,0);
        matrix[1][1]=1;
        matrix[2][2]=1;
        matrix[3][3]=1;
        return;
    }
    if(k==1){
        mem(matrix,0);
        matrix[1][1]=matrix[1][2]=matrix[1][3]=1;
        matrix[2][2]=matrix[2][3]=1;
        matrix[3][2]=1;
        return;
    }
    matrixSolve(k/2);
    ll tempMatrix[4][4];
    mem(tempMatrix,0);
    rep(i,1,3){
        rep(j,1,3){
            rep(k,1,3){
                tempMatrix[i][j]=(tempMatrix[i][j]+matrix[i][k]*matrix[k][j]%mol)%mol;
            }
        }
    }
    rep(i,1,3){
        rep(j,1,3){
            matrix[i][j]=tempMatrix[i][j];
        }
    }
    if((k&1)==1){
        ll temp2Matrix[4][4];
        mem(temp2Matrix,0);
        temp2Matrix[1][1]=temp2Matrix[1][2]=temp2Matrix[1][3]=1;
        temp2Matrix[2][2]=temp2Matrix[2][3]=1;
        temp2Matrix[3][2]=1;

        ll temp3Matrix[4][4];
        mem(temp3Matrix,0);
        rep(i,1,3){
            rep(j,1,3){
                rep(k,1,3){
                    temp3Matrix[i][j]=(temp3Matrix[i][j]+tempMatrix[i][k]*temp2Matrix[k][j])%mol;
                }
            }
        }
        rep(i,1,3){
            rep(j,1,3){
                matrix[i][j]=temp3Matrix[i][j];
            }
        }
    }

}

ll solve(int k){ //calc Sk
    ll s2=2,f2=1,f1=1;
    matrixSolve(k-2);
    ll sk=(matrix[1][1]*s2+matrix[1][2]*f2+matrix[1][3]*f1)%mol;
    return sk;
}

int main(){

    while(cin>>n>>k){
        ans=0;
        rep(i,1,n){
            scanf("%d",&a[i]);
            ans=(ans+a[i])%mol;
        }
        sort(a+1,a+1+n);
        if(k==1){
           ans=(ans+a[n-1])%mol;
           ans=(ans+a[n])%mol;
           printf("%I64d\n",ans);
        }
        else{
            int xx=a[n-1];
            int yy=a[n];
            ll ans1=(solve(k)*(ll)xx)%mol;
            ll ans2=((solve(k+1)-1)*(ll)yy)%mol;
            ans=(ans+ans1+ans2)%mol;
            printf("%I64d\n",ans);
        }
    }

    return 0;
}

 

hdu 5171 GTY's birthday gift(数学,矩阵快速幂)

标签:

原文地址:http://www.cnblogs.com/fish7/p/4309828.html

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