递推求值
时间限制:
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)
-
分析:由于n的值比较大,所以常规方法肯定会超时。根据递推式求第n个表达式的值时,通常用矩阵乘法来做。
本题要构造两个矩阵,其中一个为矩阵A,作为初始矩阵
所以利用矩阵快速幂能够快速准确地求出结果。
f2 0 0
f1 0 0
1 0 0
另一个为矩阵B
b a c
1 0 0
0 0 1
因为F(2)和F(1)是已知的,当n>=3时,每次都乘以矩阵B,就能推出下一个矩阵。而矩阵的第一行第一列的元素就是所求的结果。
代码
#include<cstdio> #include<cstring> #include<queue> #include<algorithm> #include<map> using namespace std; typedef pair<int,int > P; typedef long long LL; const int maxn=100; #define N 3 #define mod 1000007 struct Matrix { LL mat[N][N]; Matrix() { memset(mat,0,sizeof(mat)); } }; Matrix mul(Matrix a,Matrix b) { Matrix res; for(int i=0; i<N; i++) for(int j=0; j<N; j++) { for(int k=0; k<N; k++) { res.mat[i][j]+=a.mat[i][k]*b.mat[k][j]; res.mat[i][j]%=mod; } } return res; } Matrix pow_matrix(Matrix a,LL n)//矩阵快速幂; { Matrix res; for(int i=0;i<N;i++) //初始化为单位矩阵; res.mat[i][i]=1; while(n!=0) { if(n&1) res=mul(res,a); a=mul(a,a); n>>=1; } return res; } int main() { LL n,f1,f2,a,b,c,T; scanf("%lld",&T); while(T--) { scanf("%lld%lld%lld%lld%lld%lld",&f1,&f2,&a,&b,&c,&n); if(n==1) printf("%lld\n",(f1+mod)%mod); else if(n==2) printf("%lld\n",(f2+mod)%mod); else { Matrix A,B; A.mat[0][0]=f2; //构造矩阵!! A.mat[1][0]=f1; A.mat[2][0]=1; B.mat[0][0]=b; B.mat[0][1]=a; B.mat[0][2]=c; B.mat[1][0]=1; B.mat[2][2]=1; B=pow_matrix(B,n-2); A=mul(B,A); printf("%lld\n",(A.mat[0][0]+mod)%mod); } } return 0; }
-