首页 > 其他分享 >数学基础-快速幂、快速乘、矩阵快速幂

数学基础-快速幂、快速乘、矩阵快速幂

时间:2024-08-06 11:08:04浏览次数:6  
标签:Matrix int ll 矩阵 ++ 数学 ans 快速 mat

快速幂

幂运算的本质是做乘法,对于 \(a^b\),其核心思想是将指数 \(b\) 进行二进制分解,然后对 \(b\) 的每一位进行进行乘法,时间复杂度为 \(O(\log b)\)。

ll quick_power(ll a, ll b, ll p) {
    ll ans = 1 % p;
    for (; b; b >>= 1) {
        if (b & 1)
            ans = ans * a % p;
        a = a * a % p;
    }
    return ans;
}

快速乘

乘法运算的本质是做加法,对于 \(a\times b\),其核心思想是将乘数 \(b\) 进行二进制分解,然后对 \(b\) 的每一位进行进行加法,\(O(\log b)\)。

ll quick_power(ll a, ll b, ll p) {
    ll ans = 0;
    for (; b; b >>= 1) {
        if (b & 1)
            ans = (ans + a) % p;
        a = a * 2 % p;
    }
    return ans;
}

矩阵快速幂

定义矩阵类,重载乘法运算符*,方便后续使用:

template <class T>
class Matrix {
public:
    int n, m;
    vector<vector<T>> mat;
    Matrix(int _n) : n(_n), m(_n) {
        mat = vector<vector<T>>(n, vector<T>(m));
    }

    Matrix(int _n, int _m) : n(_n), m(_m) {
        mat = vector<vector<T>>(n, vector<T>(m));
    }

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

    void Input() {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                cin >> mat[i][j];
            }
        }
    }

    void Output() {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                cout << mat[i][j] << " \n"[j == m - 1];
            }
        }
    }

    Matrix I(int _n) {
        Matrix I = Matrix(_n);
        for (int i = 0; i < _n; i++) {
            I.mat[i][i] = 1;
        }
        return I;
    }
};

定义矩阵快速幂:

Matrix<int> matrix_power(Matrix<int> a, ll b) {
    Matrix<int> ans = a.I(a.n);

    for (; b; b >>= 1) {
        if (b & 1)
            ans = ans * a;
        a = a * a;
    }
    return ans;
}

1.矩阵快速幂可用于解决递推次数很大的问题,例如递推次数为 \(10^{18}\)。
此类问题的核心是确定要求的第 \(n\) 项 \(F(n)\) 需要用哪些变量,通过哪些常系数组合表示。

例题:
又见斐波那契
题目描述
给定递推式:

\[F(x)= \begin{cases} F(i-1) + F(i-2) + i^3 + i^2 + i + 1& i>1\\ 0& i=0\\ 1& i=1 \end{cases} \]

求 \(F(n)\) 的值,由于这个值可能太大,请对 \(10^9+7\) 取模。

输入描述
第一行是一个整数 \(T(1\le T\le 1000)\),表示样例的个数。
以后每个样例一行,是一个整数 \(n(1\le n\le 10^{18})\)。

输出描述
每个样例输出一行,一个整数,表示 \(F(n)\mod10^9+7\)。

问题分析

首先 \(A_n\) 的第一个元素为所求的 \(F_n\),根据 \(A_n\) 确定 \(A_{n-1}\) 中需要哪些元素,然后确定 \(B\) 中的系数,最后确定 \(A_n\) 的初值,本题中从 \(A_2\) 开始。

核心代码

void solve() {
    int n;
    cin >> n;
    if (n < 2) {
        cout << n << "\n";
    } else {
        Matrix<int> A(6, 1), B(6, 6), ans(6, 1);
        A.mat = vector<vector<int>>({{16}, {1}, {8}, {4}, {2}, {1}});
        B.mat = vector<vector<int>>({{1, 1, 1, 4, 6, 4},
                                     {1, 0, 0, 0, 0, 0},
                                     {0, 0, 1, 3, 3, 1},
                                     {0, 0, 0, 1, 2, 1},
                                     {0, 0, 0, 0, 1, 1},
                                     {0, 0, 0, 0, 0, 1}});
        ans = matrix_power(B, n - 2) * A;
        cout << ans.mat[0][0] << "\n";
    }
}

2.矩阵快速幂还可用于解决图论中根据邻接矩阵求路径长度的问题。
由于邻接矩阵 \(A\) 的 \(m\) 次幂中的每一个元素 \(A^m_{i,j}\) 即为图中从 \(i\) 到 \(j\) 长度为 \(m\) 的路径条数,故求图中路径长度为 \(m\) 的路径条数即对 \(A^m\) 中的每一个元素求和。

例题:
Walk
核心代码

    int n, m;
    cin >> n >> m;
    Matrix<int> A(n);
    A.Input();
    A = matrix_power(A, m);

    int ans = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            ans = (ans + A.mat[i][j]) % mod;
        }
    }
    cout << ans << "\n";
}

矩阵快速幂的时间复杂度为 \(O(m^3\logn)\),其中 \(m\) 为矩阵规模,\(n\) 为指数。

标签:Matrix,int,ll,矩阵,++,数学,ans,快速,mat
From: https://www.cnblogs.com/catting123/p/18344749

相关文章

  • 【笔记】矩阵
    1Template1.1轻量化灵活度较高,适合直接调用矩阵内值的情形。typedefvector<vector<int>>Matrix;voidresize(Matrix&a,intn,intm){ a.resize(n,vector<int>(m));}Matrixoperator*(constMatrix&a,constMatrix&b){ Matrixres;resize(re......
  • 短视频矩阵获客系统开发搭建-ai文案+剪辑+去水印
    短视频矩阵获客系统是指利用多个短视频平台进行协同运营,通过发布高质量的短视频内容来吸引、转化潜在客户的营销策略。该系统集合了内容生产、分发、数据分析等功能于一体,为企业提供了一站式的短视频营销解决方案。一、短视频矩阵系统的优势提高营销效率:通过整合多个平台,减少......
  • 抖音短视频矩阵系统源码部署/技术应用开发(流程全解析)
     应用场景:抖音矩阵系统源码开发搭建/短视频矩阵号系统源码开发搭建/ 抖音seo矩阵系统源码开发搭建等。抖音短视频矩阵系统源码开发对服务商有哪些要求?企业在选择服务商时,无论是考虑自用还是考虑加盟服务商,都要考评服务商是否有相关开发资质,能力证明等,除此之外,功能的......
  • 数学基础-素数
    算术基本定理任何一个大于\(1\)的正整数\(N\)都能唯一分解为有限个质数的乘积,可写作:\[N=p_1^{c_1}p_2^{c_2}...p_m^{c_m}\]其中\(c_i\)是正整数,\(p_i\)是质数,且满足\(p_1<p_2<...<p_m\)。推论:\(N\)的正约数的集合可写作:\[\{p_1^{b_1}p_2^{b_2}...p_m^{b_m}\}\]其......
  • 【题解】Solution Set - 新高一矩阵选讲「陶治霖」
    新高一矩阵选讲「陶治霖」https://www.becoder.com.cn/contest/5348「CF1970E3」Trails(Hard)考虑DP。定义\(f_{i,j}\)表示,第\(i\)天走到\(j\)的方案数。有转移:\[f_{i,j}=\sum_{k=1}^mf_{i-1,k}\times(s_jl_k+s_kl_j+s_js_k)\]https://www.luogu.com.cn/article/i......
  • 【矩阵对角线求和】求一个3*3矩阵对角线元素之和
    求一个3*3矩阵对角线元素之和,使用C语言实现具体代码:#include<stdio.h>intmain(){floata[3][3],sum=0;printf("请输入3x3矩阵的元素(按行输入):\n");for(inti=0;i<3;i++){for(intj=0;j<3;j++){scanf("%f",&a[i][j]);......
  • L1-048 矩阵A乘以B 分数 15
    //10'42"#include<iostream>usingnamespacestd;constintN=110;intarr[N][N];intbrr[N][N];intcrr[N][N];intmain(){intx1,y1;cin>>x1>>y1;for(inti=1;i<=x1;++i)for(intj=1;j......
  • 快速解密哈希算法利器Hasher:解密MD5、SHA256、SHA512、RIPEMD160等最佳工具
    文章目录一、工具概述1.1主要功能点1.2支持多种哈希算法二、安装方法三、使用教程四、结语一、工具概述Hasher是一个哈希破解工具,支持多达7种类型的哈希算法,包括MD4、MD5、SHA1、SHA224、SHA256、SHA384、SHA512等。它具有自动检测哈希类型、支持Windows......
  • 排序算法2:直接选择排序与快速排序
    目录1.直接选择排序1.1直接选择排序的优化2.快速排序2.1基准值的置位(Hoare版) 2.2挖坑法2.3lomuto前后指针前言前面我们进入了排序算的讲解。今天我们将继续学习几种重要的排序思想,好,咱们三连上车开始今天的内容。1.直接选择排序在元素的集合中选出最大值(最小值),......
  • Docker快速入门
    DockerDocker:快速构建、运行、管理应用的工具安装docker需要安装Linux虚拟机教程:‍⁠‬‍‍‍‍‌⁠‍‬‌‬‍‬‍‬‍‬Linux环境搭建-飞书云文档(feishu.cn)Linux虚拟机操作过于繁琐安装MobaXterm来解决这个问题在虚拟机中安装docker后进行以下操作CentOS7配置......