nyoj301递推求值【矩阵快速幂】

来源:互联网 发布:stc12c5a60s2编程 编辑:程序博客网 时间:2024/04/25 12:35

递推求值

时间限制: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取模后的值
样例输入
21 1 1 1 0 51 1 -1 -10 -100 3
样例输出
5999896
题目本身很简单就是一个矩阵快速幂但取模有点坑
 #include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#include<cmath>#define MOD 1000007using namespace std;long long mar[3][3];long long ans[3][3];void Mulit(long long A[3][3],long long B[3][3]){long long D[3][3]={0};for(int i=0;i<3;++i){for(int k=0;k<3;++k){if(A[i][k]){for(int j=0;j<3;++j){D[i][j]=(D[i][j]+A[i][k]*B[k][j])%MOD;}}}}for(int i=0;i<3;++i){for(int j=0;j<3;++j){A[i][j]=D[i][j];}}}void Martix(long long A[3][3],long long k){memset(ans,0,sizeof(ans));for(int i=0;i<3;++i){for(int j=0;j<3;++j){ans[i][j]=(i==j);}}while(k){if(k&1)Mulit(ans,A);Mulit(A,A);k>>=1;}}int main(){int t,i,j,k;long long f1,f2,a,b,c,n;scanf("%d",&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+MOD)%MOD);}else if(n==2){printf("%lld\n",((f2+MOD)%MOD+MOD)%MOD);}else {mar[0][0]=b;mar[0][1]=1;mar[0][2]=0;mar[1][0]=a;mar[1][1]=0;mar[1][2]=0;mar[2][0]=1;mar[2][1]=0;mar[2][2]=1;Martix(mar,n-2);printf("%lld\n",((f2*ans[0][0]+f1*ans[1][0]+c*ans[2][0])%MOD+MOD)%MOD);}}return 0;}        



0 0
原创粉丝点击