You have to find the nth term of the following function:
f(n) = a * f(n-1) + b * f(n-3) + c, if(n > 2)
= 0, if(n ≤ 2)
Input
Input starts with an integer T (≤ 100), denoting the number of test cases.
Each case contains four integers n (0 ≤ n ≤ 108), a b c (1 ≤ a, b, c ≤ 10000).
Output
For each case, print the case number and f(n) modulo 10007.
****此题难点在于推导矩阵,还有就是矩阵相乘时注意行列的变化,其余和快速幂没有什么区别*
另外单位矩阵初始化也应注意
矩阵
A:
f(1) f(i+1) f(i+2) 1
0 0 0 0
0 0 0 0
0 0 0 0
B:
0 0 b 0
1 0 0 0
0 1 a 0
0 0 c 1
#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <queue>
using namespace std;
typedef long long ll;
const ll N=4,mod=10007;
struct node
{
ll j[N][N];
};
node mul(node aa,node bb)
{
node cnt;
memset(cnt.j,0,sizeof(cnt.j));
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
if(aa.j[i][j])
for(int f=0;f<4;f++)
cnt.j[i][f]=(cnt.j[i][f]+aa.j[i][j]*bb.j[j][f])%mod;
return cnt;
}
node quick(node B,ll k)
{
node tmp;
memset(tmp.j,0,sizeof(tmp.j));
for(int i=0;i<4;i++)
tmp.j[i][i]=1;
while(k)
{
if(k%2) tmp=mul(tmp,B);
B=mul(B,B);
k/=2;
}
return tmp;
}
int main()
{
node A,B;
int t;
scanf("%d",&t);
for(int cas=1;cas<=t;cas++)
{
printf("Case %d: ",cas);//所有情况都要输出,所以最开始就要输出
memset(A.j,0,sizeof(A.j));
memset(B.j,0,sizeof(B.j));
ll n,a,b,c;
cin>>n>>a>>b>>c;
if(n<=2)
{
puts("0");
continue;
}
B.j[0][2]=b;
B.j[1][0]=1;
B.j[2][1]=1;
B.j[2][2]=a;
B.j[3][2]=c;
B.j[3][3]=1;
B=quick(B,n-2);
A.j[0][3]=1;
A=mul(A,B);
cout<<A.j[0][2]<<endl;
}
}