HDU 5950 Recursive sequence

T组数据, 每次给你 n A B 三个数字。

f[1] = A  , f[2] = B  ,  f[n] = 2 * f[n-2] + f[n-1] + n^4

 

思路: 啊啊啊啊啊 矩阵快速幂 一定先要去构造单位矩阵

 

式子1 : f[i] = 2 * f[i - 2] + f[i - 1] + i ^ 4

式子2 : f[i + 1] = 2 * f[i - 1] + f[i] + (i + 1) ^ 4

把(i + 1)^4 用二项式定理展开  (i + 1) ^ 4 = i ^ 4 + 4 * i ^ 3 + 6 * i ^ 2 + 4 * i + 1

然后把式子1写成式子2的样子

式子3 :  f[i] = 2 * f[i - 2] + f[i - 1] + i ^ 4 + 0 * i ^ 3 + 0 * i ^ 2 + 0 * i + 0 *1

也就是说 f[i+1] 只的(i+1)的4次方 可以通过 i^3, i^2, i^1, 1 构造出来。 

 

则 f[3] = 2 * f[1] + f[2] + 3^4   而3^4可以写成 (2 + 1)^4  =  1 * 2^4 + 4* i^3 + 6 * i^2 + 4 * i + 1  

^ - ^ 然后xjb构造矩阵吧   

\begin{pmatrix} f2 & f1 & { 2 }^{ 4 } & { 2 }^{ 3 } & { 2 }^{ 2 } & { 2 }^{ 1 } & 1 \end{pmatrix}\begin{pmatrix} 1 & 1 & 0 & 0 & 0 & 0 & 0 \\ 2 & 0 & 0 & 0 & 0 & 0 & 0 \\ 1 & 0 & 1 & 0 & 0 & 0 & 0 \\ 4 & 0 & 4 & 1 & 0 & 0 & 0 \\ 6 & 0 & 6 & 3 & 1 & 0 & 0 \\ 4 & 0 & 4 & 3 & 2 & 1 & 0 \\ 1 & 0 & 1 & 1 & 1 & 1 & 1 \end{pmatrix}\quad =\quad \begin{pmatrix} f2+2f1+{ 3 }^{ 4 } & f2 & { 3 }^{ 4 } & { 3 }^{ 3 } & { 3 }^{ 2 } & { 3 }^{ 1 } & 1 \end{pmatrix}

 

上代码:

//
//  HDU5950 - Recursive sequence.cpp
//  数论
//
//  Created by Terry on 2018/9/29.
//  Copyright © 2018年 Terry. All rights reserved.
//

#include <stdio.h>
typedef long long LL;
long long read(){
    long long x = 0, f = 1;
    char ch=getchar();
    while(ch < '0' || ch > '9'){if(ch=='-') f = -1; ch = getchar();}
    while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0'; ch = getchar();}
    return x * f;
}
const int maxn = 7;
const long long mod = 2147493647;
struct Matrix{
    long long m[maxn][maxn];
}unit;
Matrix operator * (Matrix a, Matrix b){
    Matrix ret;
    LL x;
    int n = 7;
    for(int i = 0; i < n; ++i){
        for(int j = 0; j < n; ++j){
            x = 0;
            for(int k = 0; k < n; ++k){
                x += ((LL)a.m[i][k] * b.m[k][j]) % mod;
            }
            ret.m[i][j] = (x) % mod;
        }
    }
    return ret;
}
void init_unit(){
    // 单位矩阵
    for(int i = 0; i < maxn; ++i){
        unit.m[i][i] = 1;
    }
}
Matrix pow_mat(Matrix a, LL n){
    Matrix ans = unit;
    while (n) {
        if(n & 1){
            ans = ans * a;
        }
        a = a * a;
        n >>= 1;
    }
    return ans;
}
int main(){
    // 初始化单位矩阵
    init_unit();
    LL T = read();
    while (T--) {
        LL n = read();
        Matrix ans, a;
        LL A = read();
        LL B = read();
        if(n == 1){
            printf("%lld\n", A);
        }
        else if(n == 2){
            printf("%lld\n", B);
        }
        else{
            ans.m[0][0] = B; ans.m[0][1] = A; ans.m[0][2] = 16; ans.m[0][3] = 8; ans.m[0][4] = 4; ans.m[0][5] = 2; ans.m[0][6] = 1;
            
            a.m[0][0]=1; a.m[0][1]=1; a.m[0][2]=0; a.m[0][3]=0; a.m[0][4]=0; a.m[0][5]=0; a.m[0][6]=0;
            a.m[1][0]=2; a.m[1][1]=0; a.m[1][2]=0; a.m[1][3]=0; a.m[1][4]=0; a.m[1][5]=0; a.m[1][6]=0;
            a.m[2][0]=1; a.m[2][1]=0; a.m[2][2]=1; a.m[2][3]=0; a.m[2][4]=0; a.m[2][5]=0; a.m[2][6]=0;
            a.m[3][0]=4; a.m[3][1]=0; a.m[3][2]=4; a.m[3][3]=1; a.m[3][4]=0; a.m[3][5]=0; a.m[3][6]=0;
            a.m[4][0]=6; a.m[4][1]=0; a.m[4][2]=6; a.m[4][3]=3; a.m[4][4]=1; a.m[4][5]=0; a.m[4][6]=0;
            a.m[5][0]=4; a.m[5][1]=0; a.m[5][2]=4; a.m[5][3]=3; a.m[5][4]=2; a.m[5][5]=1; a.m[5][6]=0;
            a.m[6][0]=1; a.m[6][1]=0; a.m[6][2]=1; a.m[6][3]=1; a.m[6][4]=1; a.m[6][5]=1; a.m[6][6]=1;

            a = pow_mat(a, n - 2);
            ans = ans * a;

            printf("%lld\n", ans.m[0][0] % mod);
        }
    }
    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值