nyoj301 递推求值
递推求值
时间限制: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
这题可以用矩阵快速幂做,构造矩阵【f(x-2),f(x-1),c 】*A=【f(x-1),f(x),c】.
0 a 0
A= 1 b 0
0 1 1
#include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<vector> #include<map> #include<set> #include<queue> #include<stack> #include<string> #include<algorithm> using namespace std; typedef long long ll; #define inf 0x7fffffff #define pi acos(-1.0) #define MOD 1000007 ll ans[3][3]; ll a,b; ll fast_mod(ll n) { ll i,j,k; ll t[3][3]={0,a,0,1,b,0,0,1,1}; ll temp[3][3]; while(n) { if(n&1){ for(i=0;i<3;i++){ for(j=0;j<3;j++){ temp[i][j]=ans[i][j]; ans[i][j]=0; } } for(i=0;i<3;i++){ for(j=0;j<3;j++){ for(k=0;k<3;k++){ ans[i][j]=(ans[i][j]+(temp[i][k]*t[k][j]%MOD) )%MOD; } ans[i][j]=(ans[i][j]+MOD)%MOD; } } } for(i=0;i<3;i++){ for(j=0;j<3;j++){ temp[i][j]=t[i][j]; t[i][j]=0; } } for(i=0;i<3;i++){ for(j=0;j<3;j++){ for(k=0;k<3;k++){ t[i][j]=(t[i][j]+(temp[i][k]*temp[k][j]%MOD) )%MOD; } t[i][j]=(t[i][j]+MOD)%MOD; } } n>>=1; } } int main() { ll n,m,i,j,T,k; ll c,d,e; ll f[3]; scanf("%lld",&T); while(T--) { scanf("%lld%lld%lld%lld%lld%lld",&f[1],&f[2],&a,&b,&c,&n); if(n==1 || n==2){ printf("%lld\n",(f[n]+MOD)%MOD ); continue; } memset(ans,0,sizeof(ans)); ans[0][0]=ans[1][1]=ans[2][2]=1; fast_mod(n-1); ll cnt; //最后的一次矩阵可以直接算 cnt=( (f[1]*ans[0][0]+f[2]*ans[1][0]+c*ans[2][0])%MOD+MOD)%MOD; printf("%lld\n",cnt); } return 0; }