HDU 2256 矩阵快速幂

传送门:HDU 2256

题意

给定n, 求(2 ^ 1 / 2 + 3 ^ 1 / 2) ^ n的整数部分, 并对1024取模


题解

推导公式
推导公式
构造矩阵


code

/*
adrui's submission
Language : C++
Result : Accepted
Love : ll
Favorite : Dragon Balls

Standing in the Hall of Fame
*/



#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
using namespace std;

#define debug 0
#define mid ((l + r) >> 1)
#define ls rt << 1, l, mid
#define rs rt << 1|1, mid + 1, r
#define LL long long
#define MOD 1024
#define M(a, b) memset(a, b, sizeof(a))

const int maxn(1e5 + 7);
int N;

struct Matrix {
    int mat[2][2], n, m;

    Matrix(int _n, int _m) {
        M(mat, 0);
        this->n = _n;
        this->m = _m;
    }

    void Debug() {
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
            {
                printf("%d%c", mat[i][j], j == m - 1 ? '\n' : ' ');
            }
    }

    void unit() {
        for (int i = 0; i < n; i++)
            mat[i][i] = 1;
    }
};

Matrix operator * (Matrix a, Matrix b) {                            //矩阵乘法
    Matrix c(a.n, b.m);
    M(c.mat, 0);
    for (int i = 0; i < a.n; i++)
        for (int j = 0; j < b.m; j++)
            for (int k = 0; k < a.m; k++)
                c.mat[i][j] = (c.mat[i][j] + a.mat[i][k] * b.mat[k][j]) % MOD;

    return c;
}

Matrix operator ^ (Matrix a, int b) {                               //快速幂
    Matrix res(2, 2);
    res.unit();

    while (b) {
        if (b & 1) res = res * a;
        a = a * a;
        b >>= 1;
    }

    return res;
}
int main() {
#if debug
    freopen("in.txt", "r", stdin);
#endif //debug

    int T;
    scanf("%d", &T);
    while (T--) {
        scanf("%d", &N);
        Matrix res(2, 2);
        res.mat[0][0] = res.mat[1][1] = 5;
        res.mat[0][1] = 12;
        res.mat[1][0] = 2;                                              //底数矩阵

        res = res ^ (N - 1);
        Matrix ans(2, 1);
        ans.mat[0][0] = 5;
        ans.mat[1][0] = 2;
        ans = res * ans;
        //ans.Debug();

        int _Ans = 2 * ans.mat[0][0] - 1;                               //ans
        printf("%d\n", _Ans % MOD);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值