蓝桥杯-算法提高-递推求值(C/C++)

考点:矩阵快速幂,确定矩阵递推公式

#include <iostream>
#include <cstring>

using namespace std;
typedef long long LL;
LL n, mod = 99999999;

LL a[7][7] = {  {0, 1, 0, 0, 2, 0, 5},
                {1, 0, 0, 0, 3, 2, 3},
                {1, 0, 0, 0, 0, 0, 0},
                {0, 1, 0, 0, 0, 0, 0},
                {0, 0, 1, 0, 0, 0, 0},
                {0, 0, 0, 1, 0, 0, 0},
                {0, 0, 0, 0, 0, 0, 1}
                };


LL b[7][1] = {  {6},
                {5},
                {1},
                {4},
                {2},
                {3},
                {1}
                };

LL c[7][7];
LL res[7][1];

LL ans[7][7] ={  {1, 0, 0, 0, 0, 0, 0},
                 {0, 1, 0, 0, 0, 0, 0},
                 {0, 0, 1, 0, 0, 0, 0},
                 {0, 0, 0, 1, 0, 0, 0},
                 {0, 0, 0, 0, 1, 0, 0},
                 {0, 0, 0, 0, 0, 1, 0},
                 {0, 0, 0, 0, 0, 0, 1}
                };

//求矩阵ans与a的和,结果保存在ans中
void mul(){
    memset(c, 0, sizeof(c));
    for(int k = 0; k < 7; k++){
        for(int i = 0; i < 7; i++){
            for(int j = 0; j < 7; j++){
                c[i][j] = (c[i][j] + ans[i][k] * a[k][j]) % mod;
                }
            }
        }
    memcpy(ans, c, sizeof(c));
}

//求矩阵a * a
void mul_a(){
    memset(c, 0, sizeof(c));
    for(int k = 0; k < 7; k++){
        for(int i = 0; i < 7; i++){
            for(int j = 0; j < 7; j++){
                c[i][j] = (c[i][j] + a[i][k] * a[k][j]) % mod;
                }
            }
        }
    memcpy(a, c, sizeof(c));
}

//求矩阵ans * b
void mul_ab(){
    memset(res, 0, sizeof(res));
    for(int k = 0; k < 7; k++){
        for(int i = 0; i < 7; i++){
            for(int j = 0; j < 1; j++){
                res[i][j] = (res[i][j] + ans[i][k] * b[k][j]) % mod;
                }
            }
        }
}

//求矩阵a的k次方
void qp(LL k){
    while(k){
        if(k & 1) mul();    //ans *= a
        mul_a();
        k >>= 1;
        }
}

int main(){
    scanf("%I64d", &n);
    if(n <= 3){
        if(n == 1) printf("2\n3\n");
        else if(n == 2) printf("1\n4\n");
        else printf("6\n5\n");
        }
    else{
        qp(n - 3);
        mul_ab();
        printf("%I64d\n%I64d\n", res[0][0], res[0][1]);
        }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值