C - Recursive sequence HDU - 5950

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 i4

. 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 < 231

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+1)^4 = n^4 + 4n^3 + 6n^2 + 4n + 1 // 一开始不知道这个公式
则构造两个矩阵就可以了
这里写图片描述

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define mod 2147493647
using namespace std;
typedef long long ll;

typedef struct{
    ll m[10][10];
}ty;

ty f(ty a, ty b){
    ty tmp;
    memset(tmp.m, 0, sizeof(tmp.m));
    for(int i = 0; i < 7; i++){
        for(int j = 0; j < 7; j++){
            for(int k = 0; k < 7; k++){
                tmp.m[i][j] += ((a.m[i][k] % mod) * (b.m[k][j] % mod)) % mod;
            }
        }
    }
    return tmp;
}
ty s(ty a, int n){
    ty tmp;
    memset(tmp.m, 0, sizeof(tmp.m));
    for(int i = 0; i < 7; i++)tmp.m[i][i] = 1;
    while(n){
        if(n & 1){
            tmp = f(tmp, a);
        }
        a = f(a, a);
        n >>= 1;
    }
    return tmp;
}
ty init(){
    ty u;
    memset(u.m, 0, sizeof(u.m));
    u.m[0][0] = 1; u.m[0][1] = 2; u.m[0][2] = 1; u.m[0][3] = 4; u.m[0][4] = 6; u.m[0][5] = 4; u.m[0][6] = 1;
    u.m[1][0] = 1; u.m[1][1] = 0; u.m[1][2] = 0; u.m[1][3] = 0; u.m[1][4] = 0; u.m[1][5] = 0; u.m[1][6] = 0;
    u.m[2][0] = 0; u.m[2][1] = 0; u.m[2][2] = 1; u.m[2][3] = 4; u.m[2][4] = 6; u.m[2][5] = 4; u.m[2][6] = 1;
    u.m[3][0] = 0; u.m[3][1] = 0; u.m[3][2] = 0; u.m[3][3] = 1; u.m[3][4] = 3; u.m[3][5] = 3; u.m[3][6] = 1;
    u.m[4][0] = 0; u.m[4][1] = 0; u.m[4][2] = 0; u.m[4][3] = 0; u.m[4][4] = 1; u.m[4][5] = 2; u.m[4][6] = 1;
    u.m[5][0] = 0; u.m[5][1] = 0; u.m[5][2] = 0; u.m[5][3] = 0; u.m[5][4] = 0; u.m[5][5] = 1; u.m[5][6] = 1;
    u.m[6][0] = 0; u.m[6][1] = 0; u.m[6][2] = 0; u.m[6][3] = 0; u.m[6][4] = 0; u.m[6][5] = 0; u.m[6][6] = 1;
    return u;
}
int main(){
    int t;
    scanf("%d", &t);
    while(t--){
       int n;
       int x, y;
       scanf("%lld %lld %lld",&n, &x, &y);
       ty op;
       op = s(init(), n - 2);
       ll sum = op.m[0][0] * y % mod+ op.m[0][1] * x % mod + op.m[0][2] * 16 + op.m[0][3] * 8 + op.m[0][4] * 4 + op.m[0][5] * 2 + op.m[0][6];
       printf("%lld\n", sum % mod);
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值