题目: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 long
using 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;
}