递推求值
时间限制:
1000 ms | 内存限制:
65535 KB
难度:
4
-
描述
-
给你一个递推公式:
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
-
第一行是一个整数T,表示测试数据的组数(T<=10000)
解题报告:这道题是矩阵快速幂模板题。
矩阵A: 矩阵B:
b a c f2 0 0
1 0 0 f1 0 0
0 0 1 1 0 0
当n>=3时,Fn=A^(n-2)*B;
code :
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
#include<sstream>
#include<algorithm>
#include<math.h>
#include<queue>
#include<stack>
#include<map>
#include<set>
using namespace std;
const int mod=1000007;/*求余*/
struct Matrix
{
int m[3][3]; /*下标从0开始*/
};
Matrix Mul(Matrix a,Matrix b)/*矩阵乘法*/
{
Matrix c;
memset(c.m,0,sizeof(c.m));
for(int i=0;i<3;i++)
for(int j=0;j<3;j++)
for(int k=0;k<3;k++)
c.m[i][j]= (c.m[i][j]+a.m[i][k]*b.m[k][j] + mod)%mod;
return c;
}
Matrix fastm(Matrix a,int n) /*矩阵a的n次方*/
{
Matrix res;/*初始化为单位矩阵*/
memset(res.m,0,sizeof(res.m));
res.m[0][0] = res.m[1][1]= res.m[2][2]=1;
while(n)
{
if(n&1) res = Mul(res,a);
n>>=1;
a = Mul(a,a);
}
return res;
}
int main()
{
// freopen("input.txt","r",stdin);
int t,n,f1,f2,a,b,c;
scanf("%d",&t);
while(t--){
scanf("%d%d%d%d%d%d",&f1,&f2,&a,&b,&c,&n);
if(n==1) printf("%d\n",f1);
else if(n==2) printf("%d\n",f2);
else{
Matrix t,k;
k.m[0][0]=f2;k.m[0][1]=0;k.m[0][2]=0;
k.m[1][0]=f1;k.m[1][1]=0;k.m[1][2]=0;
k.m[2][0]=1;k.m[2][1]=0;k.m[2][2]=0;
t.m[0][0]=b;t.m[0][1]=a;t.m[0][2]=c;
t.m[1][0]=1;t.m[1][1]=0;t.m[1][2]=0;
t.m[2][0]=0;t.m[2][1]=0;t.m[2][2]=1;
t=fastm(t,n-2);
printf("%d\n",Mul(t,k).m[0][0]);
}
}
return 0;
}