HDU - 5950 Recursive sequence (构造矩阵 + 矩阵快速幂)

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 的影响,这个递推式是很好表示的 \begin{bmatrix} F_{n + 2}\\F_{n + 1} \end{bmatrix} = \begin{bmatrix} 1 & 2\\ 1& 0 \end{bmatrix} * \begin{bmatrix} F_{n + 1}\\F_{n} \end{bmatrix} (设左边矩阵为C,右边为 A , B), 但 i ^ 4 对递推式是有影响的,可以对i ^ 4进行展开...于是有 (i + 1)^{4} = i^{4} + 4i^{3} + 6i^{2} + 4i + 1

 

而对于矩阵A的构造,首先需要理解,C 可以表示为A 和 B, 紧接着 B 又可以表示为 另一对 A1 和 B1 ... 所以要求就是,矩阵C 和 B 的模样要是一样的。

 

算上 F_{n + 2} 与 F_{n + 1} , 以及上式子的项数,于是有  7 x 1 的矩阵 C 和 矩阵 B。

\begin{bmatrix} F_{n + 2}\\ F_{n + 1}\\ (n + 2)^{4}\\ (n + 2)^{3}\\ (n + 2)^{2}\\ (n + 2)\\ 1 \end{bmatrix} = A * \begin{bmatrix} F_{n + 1}\\ F_{n}\\ (n+1)^{4}\\ (n+1)^3\\ (n+1)^2\\ (n+1)\\ 1 \end{bmatrix}, 根据这个关系,便可求出 7 x 7 的 矩阵 A,不过得注意, 通过递推式算F 的最开始的下标为 3,故 n = 1, 也就是最开始的矩阵为  (b,a,16,8,4,2,1) 的转置 .(假设为D 矩阵)

即有C_{n} = A^{n - 2} * D  ,C_{n} 表示该矩阵的 第一个元素为F_{n} 的矩阵.

 

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;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值