2023-11-13 11:39阅读: 63评论: 14推荐: 4

同余相关

取余定义: a%b=abab

整除

a|b 表示 a 能被 b 整除,即 b=a×k(kZ)

同余

ab(modm) 表示 amodm=bmodm

相当于 ab=m×k(kN)

裴蜀定理

内容

a , b 是整数,且 gcd(a,b)=d ,那么对于任意的整数 x , y , ax+by 都一定是 d 的倍数,特别地,一定存在整数 x,y ,使 ax+by=d 成立。

同余方程

axm(modb)

axm=by

ax+by=m

欧几里得算法

gcd(a,b)=gcd(b,a%b)

int gcd(int x,int y)
{
    if(!y) return x;
    return gcd(y,x%y);
}

扩展欧几里得

可以通过欧几里得求 gcd 的过程求解 ax+by=gcd(a,b)

gcd(ab)=d ,当前的式子为 ax+by=d ,则下一轮要递归的式子为 bx1+(a%b)y1=d

假设我们已经得出了 bx1+(a%b)y1=d ,需要求出 x,y

bx1+(a%b)y1=d

a%b=abab 可得

bx1+(abab)y1=d

整理得

ay1+b(x1aby1)=d

{x=y1y=(x1aby1)

边界:辗转相除最后 b=0 返回 a

所以当 b=0 时,我们令 x=1 即可( y 可以为任意数,因为 b=0 )。


求出了特解,我们就可以推出通解。

设通解为 xk,yk

{xk=x+kbgcd(a,b)yk=ykagcd(a,b)(kZ)

其实可以先求出来 xk 在将 xk 带入进原式得出 yk


设一个同余方程为 ax+by=kgcd(a,b)=d

由裴蜀定理可知,k 一定为 d 的倍数。

所以可以先求出 ax0+by0=d 的解。再求出 ax+by=k 解。

{x=x0kgcd(a,b)y=y0kgcd(a,b)

int x,y;
int exgcd(int a,int b,int &x,int &y)
{
    if(!b) {x=1,y=0;return a;}
    int d=exgcd(b,a%b,x,y);
    int t=x;
    x=y;y=t-a/b*y;
    return d;
}

逆元

ab1(modp)a,b 互质,则称 ba 的逆元。( b=inv(a) )其实就是 a 在模意义下的倒数。

扩展欧几里得求逆元

bap 意义下的逆元,由逆元定义的可得

ab+py=1

使用扩展欧几里得即可

int x,y;
void exgcd(int a,int p,int &x,int &y)
{
    if(!b) {x=1,y=0;return ;}
    exgcd(p,a%p,x,y);
    int t=x;
    x=y;y=t-a/p*y;
    return ;
}
int main(){
    a=read(),p=read();
    exgcd(a,p,x,y)
    printf("%lld",(x%p+p)%p);//( x 一直加 p 直到大于 0 )
}

费马小定理求逆元

费马小定理为:如果 p 是一个质数,而整数 a 不是 p 的倍数,则有 ap11(modp)

由逆元的定义可以得出

ainv(a)1ap1(modp)

inv(a)ap2(modp)

用快速幂计算即可

inline int qpow(int a,int p){
    int b=p-2;int base=a,ans=1;
    while(b){
        if(b&1) ans=(ans*base)%p;
        base=(base*base)%p;
        b>>=1;
    }
    return ans;
}

线性递推法

p=aq+r ,则 q=pa,r=p%a

aq+r0(modp)

arinv(q)(modp)

inv(a)qinv(r)(modp)

可得递推式:

inv(a)=(pa)inv(p%a)(modp)

int inv[M];
inline void getInv(int n,int p)
{
    inv[1]=1;
    for(int i = 2;i <= n;i++){
        inv[i]=-p/i*inv[p%i];
        inv[i]=(inv[i]%p+p)%p;
    }
}

中国剩余定理(CRT)

出自《孙子算经》

有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二。问物几何?

本质是求解一个同余方程组

{xa1(modm1)xa2(modm2)...xan(modmn)

有一个限制:mi 两两互质。

我们可以将方程组分开来看:

{x1a1(modm1)x2a2(modm2)...xnan(modmn)

只有当 m1|x2 时, x1+x2a1(modm1)

使 x=i=1nxi ,我们设 p=i=1nmi,Mi=pmi,ri=xiMi ,解下面的同余方程:

{M1r1a1(modm1)M2r2a2(modm2)...Mnrnan(modmn)

因为 mi 两两互质,可以用 exgcd 求解,即求关于 wi 的同余方程:

{M1w11(modm1)M2w21(modm2)...Mnwn1(modmn)

(相当于求 Mi 的在模 mi 意义下的逆元 inv(Mi)|mi

将解代回得 ri=aiwi

再将 ri 代回得 xi=riMi=aiMiwi=aiMiinv(Mi)|mi

解即为

xi=1naiMiinv(Mi)|mi(modp)

for(int i = 1;i <= n;i++)
        a[i]=read(),b[i]=read(),P*=a[i];
for(int i = 1;i <= n;i++)
{
    int M=P/a[i];
    ans+=(b[i]*M*inv(M,a[i]))%P;
}
posted @   tkt  阅读(63)  评论(14编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起