递推求值
时间限制: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
该题就是求一个矩阵A的n-2次幂
由
f(x-1) f(x-1) c f(x-1) f(x) c
0 0 0 *A = 0 0 0
0 0 0 0 0 0
退出我矩阵A == 0 a 0
1 b 0
0 1 1
然后乘上我们的B f1 f2 c
0 0 0
0 0 0
的最后矩阵我们的答案就是矩阵的第二个数
如果该数小于0 那么+我们的求余数1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 5 using namespace std; 6 7 #define len 1000007 8 9 typedef struct numb 10 { 11 long long a[3][3]; 12 numb() 13 { 14 memset(a,0,sizeof(a)); 15 } 16 }numb; 17 18 numb tem;//中间矩阵 19 numb x;// 20 numb y; 21 22 void set_x(numb &z,int a,int b) 23 { 24 z.a[0][1] = a; 25 z.a[1][0] = 1; 26 z.a[1][1] = b; 27 z.a[2][1] = 1; 28 z.a[2][2] = 1; 29 } 30 void set_y(numb &z,int f1,int f2,int c) 31 { 32 z.a[0][0] = f1; 33 z.a[0][1] =f2; 34 z.a[0][2] = c; 35 } 36 37 void chenfa(numb &z,numb x,numb y)//A*B 38 { 39 int i; 40 int j; 41 for(j = 0; j <3; j++) 42 for(i = 0; i < 3; i++) 43 z.a[j][i] = (x.a[j][0]*y.a[0][i]+x.a[j][1]*y.a[1][i]+x.a[j][2]*y.a[2][i] ) % len; 44 } 45 46 void judge(numb &tmp,numb z,int n)//A的次方 47 { 48 while(n) 49 { 50 if(n % 2 == 1) 51 { 52 chenfa(tmp,tmp,z); 53 } 54 n /= 2; 55 chenfa(z,z,z); 56 } 57 } 58 59 int main() 60 { 61 int t; 62 scanf("%d",&t); 63 while(t--) 64 { 65 int f1,f2,a,b,c,n; 66 scanf("%d%d%d%d%d%d",&f1,&f2,&a,&b,&c,&n); 67 if(n < 3) 68 { 69 if(n == 1) 70 printf("%d\n",f1); 71 else 72 printf("%d\n",f2); 73 } 74 else{ 75 set_x(x,a,b); 76 set_y(y,f1,f2,c); 77 numb tmp; 78 tmp.a[0][0] = 1; 79 tmp.a[1][1] = 1; 80 tmp.a[2][2] = 1; 81 82 judge(tmp,x,n-2); 83 84 chenfa(y,y,tmp); 85 //print(y); 86 87 if(y.a[0][1] > 0) 88 printf("%d\n",y.a[0][1]); 89 else 90 printf("%d\n",y.a[0][1] + len); 91 } 92 } 93 return 0; 94 }