快速幂

快速幂的作用:

就是为了快速的算出ak(mod)p,先看朴素算法,如果算a^k那么得用一个for循环,效率为O(n),但是如果使用快速幂那么效率就成变成了O(logn),所以说效率还是很高的。

原理:

因为k有[log2k]+1个二进制位,所以我们需要预处理出a20(mod)p, a21(mod)p,.....a2log2k(mod)p,一共有log2k个,因此时间复杂度是O(logk),然后再组合出ak即可,就是将ak拆成ai1ai2...的形式,整理一下就是ai1+i2+....的形式,因此我们可以分两步:

  • 第一步先处理k的二进制:假设(k)10=(110110)2,那么k的二进制形式就是25+24+22+21,因此二进制位上为1的加上即可
  • 第二步:快速处理出a20, a21....,很容易发现,a21=(a20)2,即每一项是前一项的平方

都处理完之后,就可以把ak拆成ai1ai2...的形式了

感觉自己说的都一懵一懵的,举个例子:
假设要算45(mod)9,那么我们可以将5拆解成它的二进制形式(0101),于是:

45(mod)9=420(mod)9422(mod)9=420+22(mod)9

代码:

int qmi(int a, int k, int p) {
    int res = 1;
    if(k == 0 && p == 1) return 0; //可能会出现k == 0 p == 1的情况, 需要特判
    while(k) {
        if(k & 1) res = (LL)res * a % p; //不要忘了long long很重要
        k >>= 1;
        a = (LL)a * a % p;
    }
    return res;
}

矩阵快速幂

与普通的快速幂类似,求Ak(A是一个矩阵)只不过是多了一个矩阵乘法,再有就是注意一些细节了,long long的使用,直接看代码吧

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

typedef long long LL;
const int N = 110, Mod = 1e9 + 7;
long long n, k;

void mul(LL a[][N], LL b[][N], LL c[][N]) {
    LL temp[N][N] = {0};
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            for (int k = 0; k < n; k++) {
                temp[i][j] = (temp[i][j] + (LL)b[i][k] * c[k][j] % Mod) % Mod; //防止溢出
            }
        }
    }
    memcpy(a, temp, sizeof temp);
}

int main() {
    LL a[N][N], res[N][N];
    scanf("%lld%lld", &n, &k); //因为都是long long类型 因此用lld读入
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            scanf("%lld", &a[i][j]);
            res[i][j] = a[i][j];
        }
    }
    k--;
    while(k) {
        if(k & 1) mul(res, res, a);
        mul(a, a, a);
        k >>= 1;
    }
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            printf("%lld ", res[i][j]);
        }
        puts("");
    }
    return 0;
}

还有一些典型的例题 比如fib求值,求前n项和等等,会填坑的

posted @   Xxaj5  阅读(142)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示