zoukankan      html  css  js  c++  java
  • 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
    ", a);
            return;
        }
        if (n == 2) {
            printf("%d
    ", 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
    ", 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
  • 相关阅读:
    ios webapp调试神器MIHTool
    20个正则表达式
    jQuery技巧
    浏览器判断和移动端的判断
    JavaScript 被忽视的细节
    移动端Web页面问题解决方案
    virtualenv创建虚拟环境
    init.d文件夹
    python連接mysql數據庫
    const和define的使用区别
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/6576219.html
Copyright © 2011-2022 走看看