矩阵构造+矩阵快速幂-HDU5950

来源:互联网 发布:怎样做网络推广话术 编辑:程序博客网 时间:2024/06/05 08:48

题目:http://acm.hdu.edu.cn/showproblem.php?pid=5950
题意:

给出公式f(n)=f(n-1)+f(n-2)*2+n^4给出n f[1] f[2] 求f[n]

分析:

快速幂把公式分解一下,求一下矩阵,矩阵快速幂搞一下就好

题目的难点在于矩阵的构造

题解:

典型的矩阵快速幂的运用。关键是i^4怎么维护?我们可以当成求第i+1项,那么i^4就变成了(i+1)^4。那么这时我们可以用二项式定理从i^4、i^3、i^2、i^1、i^0的组合中得到(i+1)^4。也就是说总共需要维护:f[i+1]、f[i]、(i+1)^4、(i+1)^3、(i+1)^2、(i+1)^1、(i+1)^0。矩阵如下:
这里写图片描述
这里写图片描述

#include <iostream>#include <cstdio>#include <cmath>#include <cstring>#include <algorithm>#include <cstring>#include <vector>#define ll long long#define ull unsigned long longusing namespace std;const ll mod=2147493647;struct Mat{    ll mat[7][7];    void init()    {        for(int i=0; i<7; i++)            for(int j=0; j<7; j++)                mat[i][j]=(i==j);//对矩阵初始化的函数    }};Mat multi(Mat x,Mat y){    Mat ans;    for(int i=0; i<7; i++)        for(int j=0; j<7; j++)        {            ans.mat[i][j]=0;            for(int k=0; k<7; k++)                ans.mat[i][j]=(ans.mat[i][j]+x.mat[i][k]*y.mat[k][j]%mod)%mod;        }    return ans;}Mat quick_matrix_pow(Mat x,ll n){    Mat ans;    ans.init();//矩阵快速幂中ans进行初始化    while(n)    {        if(n&1)            ans=multi(ans,x);        n>>=1;        x=multi(x,x);    }    return ans;}Mat p = {   1, 2, 1, 4, 6, 4, 1,            1, 0, 0, 0, 0, 0, 0,            0, 0, 1, 4, 6, 4, 1,            0, 0, 0, 1, 3, 3, 1,            0, 0, 0, 0, 1, 2, 1,            0, 0, 0, 0, 0, 1, 1,            0, 0, 0, 0,0, 0, 1        };//构造出来的矩阵int main(){    int t;    ll n,a,b;    scanf("%d",&t);    while(t--)    {        scanf("%I64d%I64d%I64d",&n,&a,&b);        if(n==1)            printf("%I64d\n",a);        else if(n==2)            printf("%I64d\n",b);        else        {            Mat x=p;            x=quick_matrix_pow(x,n-2);            ll ans=0;            ans=(ans+b*x.mat[0][0])%mod;            ans=(ans+a*x.mat[0][1])%mod;            ans=(ans+16*x.mat[0][2])%mod;            ans=(ans+8*x.mat[0][3])%mod;            ans=(ans+4*x.mat[0][4])%mod;            ans=(ans+2*x.mat[0][5])%mod;            ans=(ans+x.mat[0][6])%mod;            printf("%I64d\n",ans);        }    }    return 0;}
原创粉丝点击