不相信自己的人,连努力的价值都没有。|

Code_AC

园龄:3年粉丝:5关注:3

整除与同余

整除和同余理论

同余方程

定义:形如 axc (mod b)ax+by=c 的方程。

裴蜀定理

内容:a,b 为正整数,则 ax+by=c 有整数解当且仅当 gcd(a,b)c 的因数。

exgcd(扩展欧几里得算法)

扩展欧几里得算法(exgcd)——可求解 gcd,解同余方程、乘法逆元。

ax+by=cax+by=gcd(a,b)bx0+a mod by0=gcd(a,b)

内容:对于形如 ax+by=gcd(a,b) 的方程,当 b=0 时,x=1,y=0 是方程的一组特解。

bx0+(aabb)y0=gcd(a,b)ay0+(x0aby0)b=gcd(a,b)x=y0,y=x0aby0

模板
inline int exgcd(int a,int b,int &x,int &y)
{
int d=a;
if(b==0) x=1,y=0;
else d=exgcd(b,a%b,y,x),y-=(a/b)*x;
return d;
}

乘法逆元

定义:ax1(mod p),就称 ax 在模 p 意义下互为乘法逆元。

例:

若要求 (mn) mod p,则转化为 (m×invn) mod p,其中 invn 表示模 p 意义下 n 的逆元。

标准分解式

定义:将质因数分解的结果,按照质因数大小,由小到大排列,并将相同质因数的连乘积,以指数形式表示。

例:

2020 的标准分解式为 22×55×101

欧拉函数

定义:φ(n) 指在小于 n 的正整数中与 n 互质的数的个数。

求法:

1.先化为标准分解式:

n=p1k1p2k2...pLkL

2.再根据公式计算:

φ(n)=i=1rpiki1(pi1)=p|npαp1(p1)=np|n(11p)

但当 m 为合数时,且不知道 m 的因数分解式时,通常很难求出 n 的欧拉函数值 φ(m)

欧拉函数线性筛法,时间复杂度 O(n)

模板
const int MAXN=4e4+5;
int phi[MAXN],prime[MAXN],m,ans;
bool vis[MAXN];
inline void getphi()
{
phi[1]=1;
for(int i=2;i<=MAXN;i++)
{
if(!vis[i])
prime[++m]=i,phi[i]=i-1;
for(int j=1;j<=m;j++)
{
if(i*prime[j]>MAXN) break;
vis[i*prime[j]]=true;
if(!(i%prime[j]))
{
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
else phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
}
}

欧拉定理

内容:对于两个正整数 a,n,若 a,n 互质,则

aφ(n)1 (mod n)

一般常用到它的推论:对于两个正整数 a,n,若 a,n 互质,则

abab mod φ(n) (mod n)

利用这个推论,在满足 a,m 互质的前提下,即使 b 较大,我们也可以轻松地计算 ab mod m 的值。

扩展欧拉定理

通常用来解决欧拉定理的推论中 a,m 不互质时的情况。

内容:

ab{ab (mod n)(b<φ(n))ab mod φ(n)+φ(n) (mod n)(bφ(n))

费马小定理

定义:p 是一个素数,则对于任意整数 a,有

apa (mod p)ap11 (mod p)

同样可以用来求逆元。

威尔逊定理

定义:对于一个素数 p,有

(p1)!1 (mod p)

BSGS(大步小步算法)

通常用来求解离散对数问题,即求解形如 axb (mod p) 的方程的解。

内容:

k=p,令 x=ky+z,则

ax=aky+zb (mod p)akybaz (mod p)

预处理出所有 baz 并哈希存储,枚举 y 后判断是否有满足条件的即可。

模板
inline int BSGS(int a,int b,int MOD)
{
map<int,int>ma;
int cur=1,t=sqrt(MOD)+1;
for(int i=1;i<=t;i++)
{
cur=cur*a%MOD;
ma[b*cur%MOD]=i;
}
int now=cur;
for(int i=1;i<=t;i++)
{
if(ma[now]) return i*t-ma[now];
now=now*cur%MOD;
}
return -1;
}

CRT(中国剩余定理)

通常用来求解形如

{xa1 (mod p1)xa2 (mod p2)...xan (mod pn)

的同余方程的解,其中 p1,p2,...,pn 均为质数。

内容:

M=pi,mi=Mpi,ti1mi (mod p)i

那么我们可以发现 aitimi0 (mod mi),aitimiai (mod pi)

于是答案便为 aitimi (mod M)

有时需要用到龟乘

模板
inline int exgcd(int a,int b,int &x,int &y)
{
int d=a;
if(b==0) x=1,y=0;
else d=exgcd(b,a%b,y,x),y-=(a/b)*x;
return d;
}
int a[MAXN],b[MAXN],n;
inline int CRT(int mod)
{
int ans=0;
for(int i=1;i<=n;i++)
{
int M=mod/a[i];
int x,y;
int d=exgcd(M,a[i],x,y);
ans=((ans+x*M*b[i])%mod+mod)%mod;
}
return ans;
}

exCRT(扩展中国剩余定理)

内容:

对于上面的方程,假设合并两个方程:

{xa1 (mod p1)xa2 (mod p2)

那么合并出来的模数一定是 lcm(p1,p2)

于是有:x=k1p1+a1=k2p2+a2.

exgcd 求出 k1,k2 即可。

其中无解的情况就是 exgcd 无解的情况。

模板
int n,a[MAXN],b[MAXN];
inline int exgcd(int a,int b,int &x,int &y)
{
int d=a;
if(b==0) x=1,y=0;
else d=exgcd(b,a%b,y,x),y-=(a/b)*x;
return d;
}
inline int gcd(int a,int b)
{
if(b==0) return a;
else return gcd(b,a%b);
}
inline int lcm(int a,int b)
{
return a/gcd(a,b)*b;
}
inline int Mod(int x,int p)
{
return (x%p+p)%p;
}
int x0,y0;
inline int exCRT(int A,int B)
{
for(int i=2;i<=n;i++)
{
int g=Mod(b[i]-B,a[i]),d=exgcd(A,a[i],x0,y0);
if(g%d) printf("No Solution\n");
x0*=g/d,x0%=a[i]/d;
B+=A*x0,A=lcm(A,a[i]),B=Mod(B,A);
}
return B;
}

本文作者:Code_AC

本文链接:https://www.cnblogs.com/code-ac/p/16795596.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Code_AC  阅读(127)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起