专栏文章
学习笔记-数学
算法·理论参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @mimzrga0
- 此快照首次捕获于
- 2025/12/01 18:13 3 个月前
- 此快照最后确认于
- 2025/12/01 18:13 3 个月前
数学
通常以组合数学,数论及杂项等形式出现。
快速幂
用于在 时间内求 或是 的解的情况。有分治和倍增两种写法,倍增更优。核心代码如下:
CPPint fast_pow(int x,int p)
{
int res=1;
while(p){
if(p&1) res=res*x%mod;
x=x*x%mod, p>>=1;
}
return res;
}
int quick_pow(int x,int p)
{
if(!p) return 1;
int res=quick_pow(x,p>>1);
res=res*res%mod;
if(p&1) res=res*x%mod;
return res;
}
欧几里得算法
欧几里得算法用于在 复杂度内求解 的算法,其核心是:
核心代码如下:
CPPint gcd(int a,int b)
{
if(b==0) return a;
return gcd(b,a%b);
}
扩展欧几里德算法(exgcd)
用于求二元线性丢番图方程 的一组解。
设
可以得到
递归求解即可。核心代码如下:
CPPvoid ex_gcd(int a,int b,int &x,int &y)
{
if(!b) { x=1; y=0; return ; }
ex_gcd(b,a%b,y,x); y-=a/b*x;
}
用扩展欧几里得算法求出 的特解后,求 的解如下:
- 记 , 的一组特解为 ,在 两边同时乘以 ,得
- 得出 的一组特解 为
模逆元
对于非零整数,如果存在 使得 ,就称 是 模 意义下的逆元。
扩展欧几里得算法
利用扩欧求解 。得到的 模 就是 的逆元。
快速幂
由费马小定理可得对于 有
所以 等于 ,利用快速幂求解。
递推求一组逆元
对于素数 ,有递推式
模板代码如下:
CPP#include<bits/stdc++.h>
#define int long long
using namespace std;
int N,P;
int inv[3000005];
signed main()
{
cin>>N>>P;
inv[1]=1; cout<<1<<'\n';
for(int i=2;i<=N;i++){
inv[i]=(P-P/i)*inv[P%i]%P;
cout<<inv[i]<<'\n';
}
}
矩阵
不会用。
给出矩阵定义,矩阵乘法,快速幂的模板。
CPP#include<bits/stdc++.h>
#define int long long
using namespace std;
constexpr int Mod=1e9+7;
int N,k;
struct Matrix{
int mat[105][105];
Matrix operator * (const Matrix &a) const{
Matrix b;
memset(b.mat,0,sizeof b.mat);
for(int i=1;i<=N;i++)
for(int j=1;j<=N;j++)
for(int k=1;k<=N;k++)
b.mat[i][j]=(b.mat[i][j]+mat[i][k]*a.mat[k][j])%Mod;
return b;
}
}A;
Matrix fast_pow(Matrix a,int p){
Matrix res;
memset(res.mat,0,sizeof res.mat);
for(int i=1;i<=N;i++) res.mat[i][i]=1;
while(p){
if(p&1) res=res*a;
a=a*a;
p>>=1;
}
return res;
}
signed main()
{
cin>>N>>k;
for(int i=1;i<=N;i++)
for(int j=1;j<=N;j++)
cin>>A.mat[i][j];
Matrix res=fast_pow(A,k);
for(int i=1;i<=N;i++){
for(int j=1;j<=N;j++) cout<<res.mat[i][j]<<' ';
cout<<'\n';
}
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...