HDU 5950 Recursive sequence 矩阵快速幂

http://acm.hdu.edu.cn/showproblem.php?pid=5950

一开始以为i^4不能矩阵快速幂,但是结论是可以得,那么要怎么递推呢?

矩阵快速幂的思路都是一样的,matrix_a * matrix_b ^ n

其中,想要维护什么,就在matrix_a写,比如现在是F[n - 1], F[n - 2],我想要递推到下一项,那么就

会变成F[n], F[n - 1],这个时候,你就要寻找一下F[n]和F[n - 1]有什么关系。

i^4也一样,想要从i^4 递推到 (i + 1)^4,就要看看他们之间有什么关系。

那么把(i + 1)^4用二项式定理展开,就知道了。

关键要掌握矩阵快速幂的思路,都是从F[n]递推到F[n + 1],寻找一下它们之间的关系就好

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;


#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset>
const LL MOD = 2147493647;
const int maxn = 8 + 2;
struct Matrix {
    LL a[maxn][maxn];
    int row, col;
};
struct Matrix matrix_mul(struct Matrix a, struct Matrix b, LL MOD) {
    struct Matrix c = {0};
    c.row = a.row;
    c.col = b.col;
    for (int i = 1; i <= a.row; ++i) {
        for (int k = 1; k <= a.col; ++k) {
            if (a.a[i][k]) {
                for (int j = 1; j <= b.col; ++j) {
                    c.a[i][j] += a.a[i][k] * b.a[k][j];
                    c.a[i][j] = (c.a[i][j] + MOD) % MOD;
                }
            }
        }
    }
    return c;
}
struct Matrix quick_matrix_pow(struct Matrix ans, struct Matrix base, int n, LL MOD) {
    while (n) {
        if (n & 1) {
            ans = matrix_mul(ans, base, MOD);
        }
        n >>= 1;
        base = matrix_mul(base, base, MOD);
    }
    return ans;
}
void work() {
    int n, a, b;
    scanf("%d%d%d", &n, &a, &b);
    if (n == 1) {
        printf("%d\n", a);
        return;
    }
    if (n == 2) {
        printf("%d\n", b);
        return;
    }
    struct Matrix t1 = {0};
    t1.row = 1, t1.col = 7;
    t1.a[1][1] = b, t1.a[1][2] = a, t1.a[1][3] = 81, t1.a[1][4] = 27, t1.a[1][5] = 9, t1.a[1][6] = 3, t1.a[1][7] = 1;

    struct Matrix t2 = {0};
    t2.row = t2.col = 7;
    t2.a[1][1] = 1, t2.a[1][2] = 1;
    t2.a[2][1] = 2;
    t2.a[3][1] = 1, t2.a[3][3] = 1;
    t2.a[4][3] = 4, t2.a[4][4] = 1;
    t2.a[5][3] = 6, t2.a[5][4] = 3, t2.a[5][5] = 1;
    t2.a[6][3] = 4, t2.a[6][4] = 3, t2.a[6][5] = 2, t2.a[6][6] = 1;
    t2.a[7][3] = 1, t2.a[7][4] = 1, t2.a[7][5] = 1, t2.a[7][6] = 1, t2.a[7][7] = 1;

    struct Matrix ans = quick_matrix_pow(t1, t2, n - 2, MOD);
    printf("%I64d\n", ans.a[1][1]);
}


int main() {
#ifdef local
    freopen("data.txt", "r", stdin);
//    freopen("data.txt", "w", stdout);
#endif
    int t;
    scanf("%d", &t);
    while (t--) work();
    return 0;
}
View Code

 

posted on 2017-03-18 21:29  stupid_one  阅读(144)  评论(0编辑  收藏  举报

导航