zoukankan      html  css  js  c++  java
  • HDU 1757 A Simple Math Problem 矩阵快速幂

    If x < 10 f(x) = x.
    If x >= 10 f(x) = a0 * f(x-1) + a1 * f(x-2) + a2 * f(x-3) + …… + a9 * f(x-10);

    对于这样一个式子,通过矩阵与线性变换的关系,可以轻松的构造出这样的矩阵

    A0:

    9
    8
    7
    6
    5
    4
    3
    2
    1
    0

    A1:
    1 1 1 1 1 1 1 1 1 1
    1 0 0 0 0 0 0 0 0 0
    0 1 0 0 0 0 0 0 0 0
    0 0 1 0 0 0 0 0 0 0
    0 0 0 1 0 0 0 0 0 0
    0 0 0 0 1 0 0 0 0 0
    0 0 0 0 0 1 0 0 0 0
    0 0 0 0 0 0 1 0 0 0
    0 0 0 0 0 0 0 1 0 0
    0 0 0 0 0 0 0 0 1 0

    那么f(n)=A1^(n-9)*A0

    快速幂即可

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <climits>
    #include <iostream>
    #include <string>
    
    using namespace std;
     
    #define MP make_pair
    #define PB push_back
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef vector<int> VI;
    typedef pair<int, int> PII;
    typedef pair<double, double> PDD;
    const int INF = INT_MAX / 3;
    const double eps = 1e-8;
    const LL LINF = 1e17;
    const double DINF = 1e60;
    const int maxn = 11;
    LL k, mod;
    
    struct Matrix {
        int n, m;
        LL data[maxn][maxn];
        Matrix(int n = 0, int m = 0): n(n), m(m) {
            memset(data, 0, sizeof(data));
        }
    };
    
    Matrix operator * (Matrix a, Matrix b) {
        Matrix ret(a.n, b.m);
        for(int i = 1; i <= a.n; i++) {
            for(int j = 1; j <= b.m; j++) {
                for(int k = 1; k <= a.m; k++) {
                    ret.data[i][j] += a.data[i][k] * b.data[k][j];
                    ret.data[i][j] %= mod;
                }
            }
        }
        return ret;
    }
    
    Matrix pow(Matrix mat, LL p) {
        if(p == 1) return mat;
        Matrix ret = pow(mat * mat, p / 2);
        if(p & 1) ret = ret * mat;
        return ret;
    }
    
    int main() {
        int a[10];
        while(cin >> k >> mod) {
            for(int i = 0; i < 10; i++) cin >> a[i];
            Matrix A(10, 10), A0(10, 1);
            if(k < 10) cout << k % mod << endl;
            else {
                for(int i = 1; i <= 10; i++) A.data[1][i] = a[i - 1];
                for(int i = 2; i <= 10; i++) A.data[i][i - 1] = 1;
                for(int i = 1, j = 9; i <= 10; i++, j--) A0.data[i][1] = j;
                A = pow(A, k - 9);
                A0 = A * A0;
                cout << A0.data[1][1] << endl;
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    数据结构-树与二叉树-思维导图
    The last packet successfully received from the server was 2,272 milliseconds ago. The last packet sent successfully to the server was 2,258 milliseconds ago.
    idea连接mysql报错Server returns invalid timezone. Go to 'Advanced' tab and set 'serverTimezone' property
    redis学习笔记
    AJAX校验注册用户名是否存在
    AJAX学习笔记
    JSON学习笔记
    JQuery基础知识学习笔记
    Filter、Listener学习笔记
    三层架构学习笔记
  • 原文地址:https://www.cnblogs.com/rolight/p/4048981.html
Copyright © 2011-2022 走看看