zoukankan      html  css  js  c++  java
  • 矩阵快速幂

    类似于快速幂
    矩阵快速幂是一个Matrix 的k次方
    (|A|^{k}=|A|^{k/2}*|A|^{k/2})
    对于这种幂的(自己乘以自己,可以用快速幂来求)

    对于任何线性递归式,都可以进行矩阵加速
    可以吧O(n)的线性进行转换为O((log_{2}n * C))C 是常数,有题目决定

    快速幂

    Matrix ksm(Matrix a,int b){
        if(b == 0)return a;
        Matrix ans(a.n,a.m);
        int maxx = max(a.n,a.m);
        for(int i = 0; i <= maxx; i++)ans.a[i][i] = 1;
        while(b){
            if(b & 1)ans = ans * a;
            a = a * a;
            b >>= 1;
        }
        return a
    

    矩阵相乘

    Matrix operator * (const Matrix &a,const Matrix &b){
        Matrix ans(a.n,b.m);
        for(int i = 0; i < a.n; i++){
            for(int j = 0; j < b.m; j++){
                for(int k = 0; k < a.m; k++){
                    ans.a[i][j] = (ans.a[i][j] + a.a[i][k] * b.a[k][j] % mod) % mod;
                }
            }
        }
        return ans;
    }
    

    矩阵的定义

    struct Matrix{
    	int n,m;
    	int a[N][N];
    	Matrix(int x,int y):n(x),m(y){memset(a,0,sizeof(a));}
    };
    

    也可以在矩阵定义中重载

    struct Matrix{
        int n,m;
        int a[11][11];
        Matrix(int x,int y):n(x),m(y){memset(a,0,sizeof(a));}
        Matrix operator * (const Matrix &b){
            Matrix ans(n,b.m);
            for(int i = 0; i < n; i++){
                for(int j = 0; j < b.m; j++){
                    for(int k = 0; k < m; k++){
                        ans.a[i][j] = (ans.a[i][j] + a[i][k] * b.a[k][j] % mod) % mod;
                    }
                }
            }
            return ans;
        }
    };
    

    矩阵快速幂

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #define rep(i,a,b) for(int i=a;i<b;i++)
    #define mod 1000000007
    #define ll long long
    using namespace std;
    const int N = 25;
    struct Matrix{
        int n,m;
        int a[11][11];
        Matrix(int x,int y):n(x),m(y){memset(a,0,sizeof(a));}
        Matrix operator * (const Matrix &b){
            Matrix ans(n,b.m);
            for(int i = 0; i < n; i++){
                for(int j = 0; j < b.m; j++){
                    for(int k = 0; k < m; k++){
                        ans.a[i][j] = (ans.a[i][j] + a[i][k] * b.a[k][j] % mod) % mod;
                    }
                }
            }
            return ans;
        }
    };
    Matrix ksm(Matrix a,int b){
        if(b == 0)return a;
        Matrix ans(a.n,a.m);
        int maxx = max(a.n,a.m);
        for(int i = 0; i <= maxx; i++)ans.a[i][i] = 1;
        while(b){
            if(b & 1)ans = ans * a;
            a = a * a;
            b >>= 1;
        }
        return ans;
    }
    int main(){
        
        return 0;
    }
    

    矩阵快速幂进行加速

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int maxn = 15;
    int k,mod;
    int a[maxn];
    struct Matrix{
        int n,m;
        int a[11][11];
        Matrix(int x,int y):n(x),m(y){memset(a,0,sizeof(a));}
        Matrix operator * (const Matrix &b){
            Matrix ans(n,b.m);
            for(int i = 0; i < n; i++){
                for(int j = 0; j < b.m; j++){
                    for(int k = 0; k < m; k++){
                        ans.a[i][j] = (ans.a[i][j] + a[i][k] * b.a[k][j] % mod) % mod;
                    }
                }
            }
            return ans;
        }
    };
    Matrix ksm(Matrix a,int b){
        if(b == 0)return a;
        Matrix ans(a.n,a.m);
        int maxx = max(a.n,a.m);
        for(int i = 0; i <= maxx; i++)ans.a[i][i] = 1;
        while(b){
            if(b & 1)ans = ans * a;
            a = a * a;
            b >>= 1;
        }
        return ans;
    }
    Matrix x(10,10);
    int getans(int k){
        if(k < 10)return k;
        Matrix y(10,10);
        y = ksm(x,k - 9);
        int ans = 0;
        for(int i = 0; i < 10; i++){
            ans = (ans + (9 - i) * y.a[0][i] % mod) % mod;
        }
    
        return ans;
    }
    int main(){
        while(cin >> k >> mod){
            for(int i = 0; i < 10; i++){
                scanf("%d",&x.a[0][i]);
            }
            for(int i = 1; i < 10; i++){
                x.a[i][i - 1] = 1;
            }
            cout << getans(k) << endl;
        }
        return 0;
    }
    
  • 相关阅读:
    锚点定位跳转的各种实现方法
    css 布局之定位 相对/绝对/成比例缩放
    闭包,jQuery插件的写法:图片预加载
    mui 常见的效果
    根据浏览器内核判断是web/iOS/android/ipad/iphone 来打开不同的网站或页面
    有字库API方法使用一二
    tab 切换实现方法
    在线图片上传、预览、裁切、放大、缩小之 cropbox.js 的应用
    html + css3 demo
    jsfiddle 使用教程
  • 原文地址:https://www.cnblogs.com/Emcikem/p/11734074.html
Copyright © 2011-2022 走看看