Recursive sequence
Farmer John likes to play mathematics games with his N cows. Recently, they are attracted by recursive sequences. In each turn, the cows would stand in a line, while John writes two positive numbers a and b on a blackboard. And then, the cows would say their identity number one by one. The first cow says the first number a and the second says the second number b. After that, the i-th cow says the sum of twice the (i-2)-th number, the (i-1)-th number, and i4i4. Now, you need to write a program to calculate the number of the N-th cow in order to check if John’s cows can make it right.
Input
The first line of input contains an integer t, the number of test cases. t test cases follow.
Each case contains only one line with three numbers N, a and b where N,a,b < 231231 as described above.
Output
For each test case, output the number of the N-th cow. This number might be very large, so you need to output it modulo 2147493647.
Sample Input
2
3 1 2
4 1 10
Sample Output
85
369
Hint
In the first case, the third number is 85 = 2*1十2十3^4.
In the second case, the third number is 93 = 2*1十1*10十3^4 and the fourth number is 369 = 2 * 10 十 93 十 4^4.
题意:给您三个数 N,A,B . 表示第一个数 为A,第二个数为B,接下来 第 i 的数 为 第 i - 2 个数的两倍 + 第 i - 1 个数 + i ^ 4
问最后第 N 个数是多少。
思路:首先看题目的数据范围,N,A,B < 2 ^ 31 ... 肯定不可能用for打表来做,于是想到 矩阵快速幂,很显然 如果没有 i ^ 4 的影响,这个递推式是很好表示的 (设左边矩阵为C,右边为 A , B), 但 i ^ 4 对递推式是有影响的,可以对i ^ 4进行展开...于是有
而对于矩阵A的构造,首先需要理解,C 可以表示为A 和 B, 紧接着 B 又可以表示为 另一对 A1 和 B1 ... 所以要求就是,矩阵C 和 B 的模样要是一样的。
算上 与 , 以及上式子的项数,于是有 7 x 1 的矩阵 C 和 矩阵 B。
有, 根据这个关系,便可求出 7 x 7 的 矩阵 A,不过得注意, 通过递推式算F 的最开始的下标为 3,故 n = 1, 也就是最开始的矩阵为 (b,a,16,8,4,2,1) 的转置 .(假设为D 矩阵)
即有 , 表示该矩阵的 第一个元素为 的矩阵.
AC代码:
#include<bits/stdc++.h>
#define debug(x) cout << "[" << #x <<": " << (x) <<"]"<< endl
#define pii pair<int,int>
#define clr(a,b) memset((a),b,sizeof(a))
#define rep(i,a,b) for(int i = a;i < b;i ++)
#define pb push_back
#define MP make_pair
#define LL long long
#define INT(t) int t; scanf("%d",&t)
#define LLI(t) LL t; scanf("%I64d",&t)
using namespace std;
const int N = 8;
const LL mod = 2147493647;
struct mat{
LL t[N][N];
};
mat standard = {
0,0,0,0,0,0,0,0,
0,1,2,1,4,6,4,1,
0,1,0,0,0,0,0,0,
0,0,0,1,4,6,4,1,
0,0,0,0,1,3,3,1,
0,0,0,0,0,1,2,1,
0,0,0,0,0,0,1,1,
0,0,0,0,0,0,0,1
};
mat cal(mat A,mat B){
mat C;
for(int i = 1;i <= 7;i ++)
for(int j = 1;j <= 7;j ++){
C.t[i][j] = 0;
for(int k = 1;k <= 7;k ++){
C.t[i][j] = (C.t[i][j] + (A.t[i][k] * B.t[k][j]) % mod) % mod;
}
}
return C;
}
mat quick_mat(mat A,int k){
mat C;
clr(C.t,0);
for(int i = 1;i <= 7;i ++) C.t[i][i] = 1;
while(k > 0){
if(k & 1) C = cal(C,A);
A = cal(A,A);
k >>= 1;
}
return C;
}
int main()
{
int t; scanf("%d",&t);
while(t --){
int n,a,b; scanf("%d%d%d",&n,&a,&b);
if(n == 1){ printf("%d\n",a); continue; }
if(n == 2){ printf("%d\n",b); continue; }
mat f;
f.t[1][1] = (LL) b; f.t[2][1] = (LL) a;
f.t[3][1] = (LL) 16; f.t[4][1] = (LL) 8;
f.t[5][1] = (LL) 4; f.t[6][1] = (LL) 2;
f.t[7][1] = (LL) 1;
mat ans;
ans = quick_mat(standard,n - 2);
ans = cal(ans,f);
printf("%I64d\n",ans.t[1][1]);
}
return 0;
}