版权声明:原创,未经作者允许禁止转载 https://blog.csdn.net/Mr_wuyongcong/article/details/86708968
文章目录
前言
因为老是懒得打模板的时候老是扣不到自己的标(因为之前的都打得太丑了),所以导致我十分的不爽。便打算开一个模板库。会不断更新的
数论数学模板
(某些附有证明)
GCD
int gcd(int a,int b)
{
if (b==0)
{return a;}
return gcd(b,a%b);
}
exgcd
展开
拆开括号
将
和
取出
将两边的
和
取出
然后由于两边是等价的
#include<cstdio>
using namespace std;
int x,y,a,b,k;
void gcd(int a,int b)
{
if (b==0)
{x=1;y=0;return;}
gcd(b,a%b);
k=x;x=y;y=k-a/b*y;
return;
}
int main()
{
scanf("%d%d",&a,&b);
gcd(a,b);
printf("%d",(x+b)%b);
}
快速幂
ll power(ll x,ll b)
{
if(!b) return 1;
ll ans=1;
while(b){
if(b&1) ans=ans*x%XJQ;
x=x*x%XJQ;b>>=1;
}
return ans;
}
线性推逆元
首先对于p,我们将其分解为
,然后有
左右两边同时乘上一个
反正本来就要
因为
比
小,按照递推的顺序我们在求出
之前就已经求出
了。但是我们还要保证不是负数,所以我们可以直接计算
#include<cstdio>
using namespace std;
int n,p;
long long inv[3000010];
int main()
{
scanf("%d%d",&n,&p);
inv[1]=1;
printf("%d\n",inv[1]);
for(int i=2;i<=n;i++)
inv[i]=(long long)p-p/i*inv[p%i]%p,printf("%d\n",inv[i]);
}
逆元求组合数
ll power(ll x,ll b)
{
ll ans=1;
x%=XJQ;
while(b){
if(b&1) ans=ans*x%XJQ;
x=x*x%XJQ;b>>=1;
}
return ans;
}
ll C(ll n,ll m)
{
ll ans1=1,ans2=1;
for(ll i=n-m+1;i<=n;i++)
ans2=ans2*i%XJQ;
for(ll i=1;i<=m;i++)
ans1=ans1*power(i,XJQ-2)%XJQ;
return ans2*ans1%XJQ;
}
矩阵乘法
struct matrix{
ll a[size][size];
}f;
matrix operator *(matrix &a, matrix &b) {
matrix c;
memset(c.a,0,sizeof(c.a));
for (ll i=0;i<size;i++)
for (ll j=0;j<size;j++)
for (ll k=0;k<size;k++)
(c.a[i][j]+=a.a[i][k]*b.a[k][j])%=YMW;
return c;
}
void ksm(matrix &f,ll b) {
matrix a=f;
while(b)
{
if(b&1) a=a*f;
f=f*f;
b>>=1;
}
f=a;
}
线性筛素数-欧式筛
void primes()
{
for(ll i=2;i<=N;i++)
if(!v[i])
{
prime[++cnt]=i;
s[i]=1;//素数也标记
for(ll j=2;i*j<=N;j++)
{
if(!v[j]&&j<=i)//是素数的乘积
s[i*j]=1;
v[i*j]=true;
}
}
}
线性筛素数-线性筛
挖坑
线性筛欧拉-欧式
for (int i=2;i<=n;i++) phi[i]=i;//初始化欧拉
for (int i=2;i<=n;i++)
{
if (phi[i]==i)//质数
for (int j=i;j<=n;j+=i)
phi[j]=phi[j]/i*(i-1);//筛去一个质因子
sum+=phi[i];//统计答案
}
线性求欧拉
ll phi(ll n)//求欧拉函数
{
ll ans=n;
for (ll i=2;i*i<=n;i++)
if (n%i==0)
{
ans=ans/i*(i-1);
while (n%i==0) n/=i;
}
if (n>1) ans=ans/n*(n-1);
return ans;
}
龟速乘
ll ksc(ll a,ll b)
{
a%=YMW;b%=YMW;
ll c=(long double)a*b/YMW;
ll ans=a*b-c*YMW;
if(ans<0) ans+=YMW;
else if(ans>=YMW) ans-=YMW;
return ans;
}
dp模板
背包
有时间再补
LIS
有时间再补
最长公共子序列
有时间再补