洛谷网校:数论(二)

2020.1.29

数论(二)

1.线性组合

给定整数{x~1~,x~2~,x~3~,...,x~n~}和k

求任意一组整数{a~1~,a~2~,a~3~,...,a~n~}

满足a~1~x~1~+a~2~x~2~+a~3~x~3~+...+a~n~x~n~=k,或返回无解。

解法

设d=gcd(x~1~,x~2~,...,x~n~)显然仅当d|k时有解(k可以看成n组d的和)

若n=1则直接令a~1~= k/x~1~。(只有一个数)

否则用gcd(x~n−1~,x~n~)代替x~n-1~和x~n~,递归构造解;(将两个数合并成一个)

回溯时调用exgcd(x~n−1~,x~n~),求出相应的a~n-1~,a~n~,使a~n-1~x~n-1~+a~n~x~n~=gcd(x~n-1~,x~n~)

用x~n−1~,x~n~的线性组合替代 (x~n−1~, x~n~)。

2.逆元

若ax≡1(mod b),则称x是a关于模b的逆元,常记做a^−1^。(和a的倒数不同!这里指只要符合ax%b=1就可,也就是说ax的值可以是:1,b+1,···,yb+1(y为任意整数))

上式等价于ax+by=1(ax,by异号)

因此逆元不一定存在,存在的充要条件为gcd(a,b)=1(a,b互质,若不互质,a模b余数一定整除gcd(a,b))

推论:如果p是质数,且p不整除a(互质),则a模p的逆元存在。

证明:[0,b)的范围内,a关于模b的逆元(整数)(若存在)是唯一的。

定义式可化为:ax%b=1,在这个式子中,x=0和x=b是等价的

反证法,若a有两个逆元0<x~1~<x~2~<b

即ax~1~≡ax~2~≡1(mod b)(两积同余1)

那么有b|a(x~2~−x~1~)成立(余数相减抵消,故:b|(ax~2~-ax~1~)),与0<x~2~−x~1~<b矛盾

求逆元

1.exgcd

因为gcd(a,b)=1

所以exgcd求的ax+by=gcd(a,b)就是ax+by=1

2.递推

假设现在要求i mod 质数p的逆元

考虑带余除法,设p=iq+r,q=p/i,r=p%i

则有iq+r≡0(mod p)(二者相等,商0余0)

注意到p是质数,因此r不为0(若r为0,则p有除1和本身以外的因数,故r不为0),r的逆元存在(gcd(r,p)=1,任何非零数和质数互质)

iq+r≡0(mod p)两边乘i^−1^r^−1^,(这里^-1^不是倒数,是逆元!i·i^-1^%p=1,r·r^-1^%p=1)因为i·i^-1^=yp+1,r·r^-1^=y~0~p+1,所以:

原式 –> qr^-1^(yp+1)+i^-1^(y~0~p+1)≡0(mod p) –> qr^-1^yp+qr^-1^+i^-1^y~0~p+i^-1^≡0(mod p) –> qr^-1^+r≡0(mod p) (将多项式中带有p的项消掉了)

推得式子:qr^−1^+i^−1^≡0(mod p) –> qr^−1^+i^-1^=i^-1^-(-qr^-1^)

易证:若a+b%c=0,那么a≡-1b(mod c),q=p/i,r=p%i

因此i^−1^≡−qr^−1^≡−(p/i)(p%i)^−1^(mod p) –> i^-1^%p=−qr^−1^%p –> i^-1^=kr^-1^-qr^-1^%p(k为正整数,保证kr^-1^和qr^-1^的差大于0)

因为r·r^-1^=yp+1,所以r^-1^=(yp+1)/r,

代码
for(inv[1]=1,i=2;i<=n;i++)//1%任何大于1的数都是1,所以inv[1]=1
    inv[i]=(p-q)*inv[r]%p;//这里的k取p,因为q永远不会比p大,所以p作k足矣

3.倒推

先用方法1(exgcd)求n!的逆元(注:这里所有bulabula^-1^都是逆元,不是倒数)

推导:((k-1)!·((k-1)!)^-1^)%p=1 –> ((k-1)!)^-1^·(k-1)!=xp+1 –> ((k-1)!)^-1^=(xp+1)/(k-1)! (x和下面的y是正整数,x=(((k-1)!)^-1^·(k-1)!)/p),y=(k!·(k!)^-1^)/p)

同理:(k!)^-1^=(yp+1)/k! –> k·(k!)^-1^=(yp+1)/(k-1)!

因为:xp+1≡yp+1(mod p)(同余1)

所以:(xp+1)/(k-1)!≡(yp+1)/(k-1)!(mod p)(在整除的情况下成立,并且由于xp+1,yp+1本就是乘出来的,所以保证了整除)

可得:((k−1)!)^−1^≡k·(k!)^−1^(mod p)

最后:((k-1)!)^-1^=k·(k!)^-1^%p(逆元永远大于0小于取模的p,所以可以求得唯一的逆元)

这样就可以倒推求出1!~(n − 1)!的逆元

因为要求k的逆元,所以继续推导:

根据定义:k·k^-1^=xp+1(x为正整数,x=(k·k^-1^)/p)

推得:k^-1^=(xp+1)/k

同理:(k!)^-1^=(yp+1)/k!

等式两边同乘(k-1)!:(k-1)!·(k!)^-1^=(yp+1)/k

因为:(xp+1)%p=1,(yp+1)%p=1

所以:(xp+1)/k≡(yp+1)/k(mod p)

也就是:k^−1^≡(k−1)!·(k!)^−1^(mod p)

最后:k^-1^=((k−1)!·(k!)^−1^)%p

就可以求出1~n的逆元了

例题:组合数取模

求C(n, k)%998244353(一个质数)

T≤105,0≤k≤n≤107

公式:

[C_{n,k}=frac {n!}{k!*(n − k)!} ]

要求:O(1)回答询问

线性求逆,预处理n!以及n!的逆元

那么C~n,k~=n!·(k!)^-1^·((n-k)!)^-1^ (因为要取模,所以除以一个数就相当于乘这个数和取模数的逆元)

3.线性同余方程

形如ax≡c(mod b)的方程,称为线性同余方程。

等价于ax+by=c(x,y有正有负)因此有解条件为gcd(a,b)|c

若(a,b)=1,则x有唯一解x≡a^−1^·c(mod b)(逆元不是倒数)

推导:易证c和c%b在方程中等价,所以使c=c%b

设整数k=(a·a^-1^)/b,所以a·a^-1^=kb+1

所以:c·a·a^-1^=k·b·c+c

整理得:c·a·a^-1^-b·k·c=c

很显然,在ax+by=c方程中,x=c·a^-1^,y=-k·c(我们不关心y是多少)

当然,a^-1^·c是可以大于b的,所以要求x,要给a^-1^·c取模

a,b不互质的情况:

设gcd(a,b)=d a=a′d b=b′d c=c′d

(这时a,b不互质,加上之前交代的有解条件gcd(a,b)|c,所以d=gcd(a,b,c))

所以a′,b′互质,按照互质的情况求出a′x+b′y=c′的解,因为等式两边同除以d,所以在这里求出的x,y在原方程仍然适用

线性同余方程组

考虑形如 x ≡ ai(mod mi) 的若干方程联立得到的方程组,如:

x≡2(mod 3) (1)

x≡3(mod 5) (2)

x≡5(mod 7) (3)

解法:

设x=3y+2,代入(2)

3y+2≡3(mod 5) –> 3y≡1(mod 5)

gcd(3,5)=1

3^-1^(mod 5)=2

由线性同余方程解法可得:y≡2*1(mod 5)

解得y≡2(mod 5)

设y=5z+2,代入(3)

3(5z+2)+2≡5(mod 7) –> 15z+6+2≡5(mod 7) –> 15z+8≡5(mod 7) –> 15z≡-3(mod 7) –> 15z≡4(mod 7)

gcd(15,7)=1

15^-1^(mod)=1

由线性同余方程解法可得:z=4*1(mod 7)

解得z≡4(mod 7)(z%7=4)

设z=7k+4,带回y=5z+2

y=5(7k+4)+2=35k+20+2=35k+22

带回x=3y+2

x=3(35k+22)+2=105k+68

x%105=68

也就是:x≡68(mod 105)

中国剩余定理

对于同余方程组x≡a~i~(mod m~i~)(i=1~n)

设M=m~1~m~2~...m~n~,M~i~=M/m~i~

若m~i~两两互质,则x在mod M下有唯一解。

中国剩余定理同时也给出了构造解的方法:

因为m~i~两两互质,所以m~i~的质因数在M~i~中不出现,所以gcd(M~i~,m~i~)=1,所以M~i~关于模m~i~的逆元存在。(逆元定义)

把这个逆元设为t~i~,于是有:

M~i~t~i~≡1(mod m~i~)

设正整数j/=i

因为m~j~是M~i~的因子,所以M~i~%m~j~=0

因为t~i~是整数,所以:M~i~t~i~%m~j~=0

前面有:M~i~t~i~≡1(mod m~i~)

等式两边同时乘a~i~,得:a~i~M~i~t~i~≡a~i~(mod m~i~)

同理:a~i~M~i~t~i~≡0(mod m~j~)

所以每个(a~i~M~i~t~i~)只对自己对应的m~i~取模时有余数,对其他m~j~取模答案都为0,这样一来,如果把所有(a~i~M~i~t~i~)都加起来,用这个和对M取模后的余数只有a~i~,满足i取任意正整数时,x≡a~i~(mod m~i~)的要求,也就解出了方程组

因此解为x≡a~1~M~1~t~1~+a~2~M~2~t~2~+...+a~n~M~n~t~n~(mod M)

代码:

int crt(int a[],int m[],int n) {//不是递归
    int M=1,ret=0;//ret就是x的解的余数部分(模数部分就是M)
    for(int i=1;i<=n;i++)
    	M*=m[i];//累乘M
    for(int i=1;i<=n;i++) {
        int Mi=M/m[i],ti=inv(Mi,m[i]);//Mi随用随算,逆元函数提前写好
        ret=(ret+a[i]*Mi*ti)%M;//累乘处理ret
    }
    return ret;
}
原文地址:https://www.cnblogs.com/Wild-Donkey/p/12243765.html