关于快速那些事
这段时间学了些关于快速∗的东西,及时复习一下以免忘记
快速幂
求bpmod k,其中p是个很大的数,比如……10100
暴力就t了,所以我们考虑
如果p是偶数,那么bp=bp/2×bp/2
如果p是奇数,那么bp=bp/2×bp/2×b
这个过程可以一直下去,最后时间复杂度就是O(log(p))的
Code
s=1;
while (p)
{
if (p&1)s=s*b%k;
b=b*b%k;
p>>=2;
}
快速(龟速)乘
求a×b mod k,其中a,b都是长整型数,也就是说相乘就会爆long long
怎么办呢,我们仍然考虑和快速幂一样的思路
如果b是偶数,那么a×b=a×(b/2)+a×(b/2)
如果b是奇数,那么a×b=a×(b/2)+a×(b/2)+a
这个过程跟快速幂很类似,虽然时间是O(log(b))的,但很好的避免了爆long long的问题
不过话虽这么说,多个大常数很容易使程序t掉,所以如果不得已最好不要用快速乘
Code
s=0;
while (b)
{
if (b&1)s=(s+a)%k;
a=a*2%k;
b>>=1;
}
口胡代码,有错见谅
矩阵快速幂
给你一个方阵A,求Ak mod p
既然是快速幂,那肯定避免不了乘法,首先我们要了解矩阵乘法的定义
设A,B是两个矩阵,C=A×B那么
-
A的列数必须和B的行数相等
-
如果A是n×r的矩阵,B是r×m的矩阵,那么C是一个n×m的矩阵
-
Ci,j=∑rk=1Ai,k×Bk,j
-
根据运算过程,显然矩阵乘法只有结合律没有交换律
而对于矩阵的乘幂来说,只有方阵,即行列个数相等的矩阵,可以进行乘幂运算
在此,我们还需要了解一个概念——单位矩阵
主对角线上的元素都是1,通常用I或E表示,图长这样子
I=[1000001000001000001000001]
这个东西可是非常的有用,任何数乘它都等于那个数本身,相当于线性运算中的1
然后矩阵快速幂就很好写出来啦
#include <iostream>
#include <cstdio>
#include <cstring>
#define int long long
using namespace std;
int n,k,p=1e9+7,a[500][500],s[500][500],b[500][500];
void jzc(int x[500][500],int y[500][500])
{
memset(b,0,sizeof(b));
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
for (int k=1;k<=n;k++)
b[i][j]=(b[i][j]+x[i][k]*y[k][j])%p;
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
x[i][j]=b[i][j];
}
signed main()
{
cin>>n>>k;
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
cin>>a[i][j],s[i][i]=1;
while (k)
{
if (k&1)jzc(s,a);
jzc(a,a);
k>>=1;
}
for (int i=1;i<=n;i++)
{
for (int j=1;j<=n;j++)
cout<<s[i][j]<<" ";
cout<<endl;
}
return 0;
}
可能还会有其他的一些快速∗,以后学了会补充上。咕咕咕
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
· ThreeJs-16智慧城市项目(重磅以及未来发展ai)
· .NET 原生驾驭 AI 新基建实战系列(一):向量数据库的应用与畅想
· Ai满嘴顺口溜,想考研?浪费我几个小时
· Browser-use 详细介绍&使用文档
· 软件产品开发中常见的10个问题及处理方法