描述
给你一个递推公式:
f(x)=a*f(x-2)+b*f(x-1)+c
并给你f(1),f(2)的值,请求出f(n)的值,由于f(n)的值可能过大,求出f(n)对1000007取模后的值。
注意:-1对3取模后等于2
输入
第一行是一个整数T,表示测试数据的组数(T<=10000)
随后每行有六个整数,分别表示f(1),f(2),a,b,c,n的值。
其中0<=f(1),f(2)<100,-100<=a,b,c<=100,1<=n<=100000000 (10^9)
输出
输出f(n)对1000007取模后的值
样例输入
2
1 1 1 1 0 5
1 1 -1 -10 -100 3
样例输出
5
999896
这是矩乘的模板题了,需要注意的两点:数组不要开大,
每次%的时候 (+mod)%mod
这里写代码片
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#define LL long long
using namespace std;
const int mod=1000007;
const int N=11; ///这个地方取值大了后会T QAQ
LL f1,f2,a,b,c,p;
int n;
LL MOD(LL x)
{
return (x%mod+mod)%mod;
}
struct node{
LL m[N][N];
node operator * (const node &a) const
{
node ans;
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
{
ans.m[i][j]=0; //初值化,避免出错
for (int k=1;k<=n;k++)
ans.m[i][j]=(ans.m[i][j]+(LL)m[i][k]*a.m[k][j])%mod; //
}
return ans;
}
node KSM(LL p)
{
p--; ///
node ans=(*this),a=(*this);
while (p)
{
if (p&1)
ans=ans*a;
a=a*a;
p>>=1;
}
return ans;
}
};
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%lld%lld%lld%lld%lld%lld",&f1,&f2,&a,&b,&c,&p);
node ans,m;
if (p==0){
printf("%lld
",(f2-f1*b-c + mod)%mod);
}
else if (p==1){
printf("%lld
",MOD(f1));
}
else if (p==2) {
printf("%lld
",MOD(f2));
}
else{
m.m[1][1]=b;m.m[1][2]=1;m.m[1][3]=0;
m.m[2][1]=a;m.m[2][2]=0;m.m[2][3]=0;
m.m[3][1]=1;m.m[3][2]=0;m.m[3][3]=1;
n=3;
ans=m.KSM(p-2);//因为前两项已经给出,所以矩阵我们只有乘p-2次
printf("%lld
",MOD(MOD(f2*ans.m[1][1])+MOD(f1*ans.m[2][1])+MOD(c*ans.m[3][1])));
} //取%的限制真是丧心病狂,还有就是注意原始方程,不要乘错了
}
return 0;
}