数论笔记Ⅰ

数论笔记Ⅰ

此处笔记Ⅱ

前言

数论专题,2022清北学堂所授,当然他讲课的课件不敢恭维,所以全部都是自学的((
Link
此处 PDF 版本,可能有些许错误在写的时候写错了,望指正。
Latex 修好啦!

同余

a,b 为两个整数,且他们的差 ab 能被某个自然数 m 所整除,则称 ab 关于 m 同余,记作 ab(modm)。它意味着 ab=m×k

​ 一些性质:

  • ab(modm),则 a+cb+c(modm)

  • ab(modm),则 a×cb×c(modm)

  • ab(modm),cd(modm),则 a×cb×d(modm)

  • ab(modm) ,则 axbx(modm)

  • a×bmodmamodm×bmodm

  • amodp=x,amodq=x,且 p,q 互质,则 amod(p×q)=x

    (感谢梓苏的友情赞助)

欧几里得算法(辗转相除法)

一条性质:zxz|y,则 z(yx),显然。

对于减法,设 y=kx+b,则我们需要减 k 次,但是发现最后的 b 完全可以用取模取出来的。

所以得到了 Gcd(a,b)=Gcd(b,amodb)

int Gcd(int a,int b){return !b?a:Gcd(b,a%b);}

如果又有某个毒瘤卡你,让你每次取模的 b 都恰好小于 x ,复杂度在 log 级别,单次最坏复杂度 O(logV)

扩展欧几里得算法

定理:如果任意整数 ab 都不为 0,则 gcd(a,b)ab 的线性组合集ax+by,aZ,bZ中的最小正元素。

我们先证一下这个定理。

证明:设 s 是线性组合集中的最小正元素,则 s=ax+by ,再设 q=ac,则 amods=aqs=aq(ax+by)=a(1qx)+b(qy),所以amods 也是 ab 的线性组合,由 s 为最小正元素,则 amods一定为零,同理可证 bmods也为零,则 sab 的公约数,则 sgcd(a,b),又因为 sab 的线性组合,则 gcd(a,b)s ,则 gcd(a,b)s ,所以 s=gcd(a,b)

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

由上面飞鼠斐蜀定理可知,ax+by=gcd(a,b) 一定有解。根据欧几里得算法,gcd(a,b)=gcd(b,amodb),所以(一把子式子):

ax1+by1=gcd(a,b),bx2+(amodb)y2=gcd(b,amodb)

gcd(a,b)=gcd(b,amodb)

ax1+by1=bx2+(amodb)y2

mod 用除法表示,则

ax1+by1=bx2+(abb)y2

ax1+by1=ay2+b(x2aby2)

b=0 时,一定有 x=1,y=0 ,递归回去即可,于是有了上面代码。

Exgcd 是可以求多解的,感谢 Konnyaku 的深情讲解。

a(x0+bgcd(a,b))+b(y0agcd(a,b))=ax0+by0

显然把第一个式子化出来是和第二个式子等价的,但是为什么要bgcd(a,b)agcd(a,b)呢?因为这俩玩意是令原式成立的最小的整数.

所以 x 的通解是 x+bgcd(a,b)×ttZ

逆元

乘法逆元 - BlackDan - 博客园

推销自己博客不过分吧。

质数筛

从娃娃时我们就学筛质数

for(int i=2;i<=sqrt(x);i++) if(!(x%i)) return 0;

复杂度为 O(nn)

而后学的是埃筛,就是筛到一个数,把他的倍数全干掉喽。

void Is_prime(int n){
    memset(vis,true,sizeof vis);
    for(int i=2;i<=n;i++){
        if(!vis[i]) continue; 
        for(int j=i*i;j<=n;j+=i)
            vis[j]=false;
    }
}

有兴趣可以看复杂度怎么证明,反正我没兴趣Eratosthenes筛法时间复杂度分析_Gavin_Nicholas

大概是Ω(nloglogn)O(nlogn)?

有的时候毒瘤出题人卡你俩 log ,所以我们有线性的欧拉筛。

int tmp[MAXN], Cnt = 0;
bool vis[MAXN];
void Init(int limit) {
    for(int i = 2; i <= limit; ++i) {
        if(!vis[i]) tmp[++ Cnt] = i;
        for(int j = 1; j <= Cnt && i * tmp[j] <= limit; ++j) {
            vis[i * tmp[j]] = true;
            if(i % tmp[j] == 0) break;
            // 欧拉筛每次都用最小质因子去筛每一个数
            // 在这里,因为 i 里面有 tmp[j] 这个因子,所以对于后面的 i * tmp[k] 来说
            // 可以拆成 i/tmp[j] * tmp[j] * tmp[k],而 tmp[j] < tmp[k]。
            // 所以要 break;
        }
    }
}

再次感谢梓苏

求解模线性方程

模线性方程即为axb(modn)x 进行求解。

定理:方程 ax+by=c 与方程 axc(modb) 是等价的,有整数解的充要条件是 gcd(a,b)c

1 眼大雾,第 2 眼还是大雾,第 3 眼依然大雾

证明一下,对于一个模线性方程axb(modn),设q=axmodn=bmodn,则有ax=k1n+q,b=k2n+q(k1.k2Z),两项作差得,axb=n(k1k2) ,移项得 axn(k1k2)=b ,令 y=(k1k2),式子为 ax+ny=b这玩意怎么这么眼熟?草,斐蜀定理,所以使式子有解要满足 gcd(a,n)b,证毕。

那这玩意?扩欧搞出一组 ax+by=gcd(a,b) 的解。

两遍同时除以 gcd(a,b) 再乘上 c 即可。

bool Co_eq(int a,int b,int c,int &x,int &y){
    int t=Exgcd(a,b,x,y);
    int k=c/t;
    if(!(c%t)) return false;
    x*=k;y*=k; return true;
}

中国剩余定理(Chinese remainder theorem、CRT)

鸣谢中国剩余定理(CRT)-知乎

引入都见过

《孙子算经》:“今有物不知其数,三三数之剩二,五五数之剩三,七七数之剩二,问物几何?”

​ 化成式子就是这个样子 {x2(mod3)x3(mod5)x2(mod7)

一个整数除以3余2、除以5余3、除以7余2,求这个整数。
答案:23
解法:由于除以3余2,因此加上一个140;由于除以5余3,因此加上一个63;由于除以7余2,因此加上一个30;这三个数的和是140+63+30=233,再减去210,就得到了23了。
这么说吧,只要是除以3余了一个1,就加上一个70;只要是除以5余了一个1,就加上一个21;只要是除以7余了一个1,就加上一个15。然后累加。超过了106就减去105就行了。

当然你可以手算这个,那数大了呢,式子多了呢?

中国剩余定理登场了,老祖宗发明的,嘿。

一个问题:计算一个整数 x ,使得它满足除以 32 、除以 53 、除以 72

如果能够找到三个整数 x1,x2,x3 使得:

{x12(mod3)x10(mod5)x10(mod7)x20(mod3)x23(mod5)x20(mod7)x30(mod3)x30(mod5)x12(mod7)

x=x1+x2+x3,易得

{x2(mod3)x3(mod5)x2(mod7)

x1x2x3 为问题 的解,看出三个问题的本质事类似的。

对于问题 11 继续分解,如果能找到一个整数 y1 满足

{y11(mod3)y10(mod5)y10(mod7)

那么令 x1=2y1,很显然这样的 x1 满足 11,所以我们扩展问题,定义新三个问题为

{y11(mod3)y10(mod5)y10(mod7)y20(mod3)y21(mod5)y20(mod7)y30(mod3)y30(mod5)y11(mod7)

这三个问题的本质是相同的,如果找到了 y1y2y3 ,那么就可以取 x=2×y1+3×y2+2×y3

以问题 ①-① 为例,就是寻找一个整数 z 使得

{z1(mod3)z0(mod5)z0(mod7).

于是 z 一定是 5×7=35 的倍数,假设 z=35k ,则有 35k1(mod3),这 k 是什么?就是 5×7mod3 的逆元,将这个 k 记作[351]3,那此时 z 就等于 5×7×[(5×7)1]3,恰好就是 5×7×2=70,对应了上面的解法中的 70

以此类推,问题①-②的解答就是 3×7×[(3×7)1]5,恰好就是 3×7×1=21

问题①-③的解答就是 3×5×[(3×5)1]7,恰好就是 3×5×1=15,都与上面对应。

所以将问题的分解复原,可得:

x=2×(5×7×[(5×7)1]3)+3×(3×7×[(3×7)1]5)+2×(3×5×[(3×5)1]7)

最后注意到 x+3×5×7也满足条件,因此要计算最小负整数,只需要 summod(3×5×7) 即可。

如果有多组解满足条件呢?他们之间又有什么联系?

假设 X,Y 都满足 “除以 3a、除以 5b、除以 7c ”。观察发现 XY 满足 “除以 30 、除以 50 、除以 70”。因此 XY 一定是 105 的倍数,也就是说在模 105 的意义下,通过分解,组合解答的 x 恰是唯一解。

把这个问题一般化:假设整数 m1,m2,mn ,且两两互质,则对于任意 a1,a2,,an,方程组:

{xa1(modm1)xa2(modm2)xa3(modm3)

都存在整数解,若 XY 同时满足该方程组,必有 XY(modN),其中 N=i=1nmi

具体而言,将上面过程表示成式子即:

xi=1nai×Nmi×[(Nmi)1]mi(modN)

int Exgcd(int a,int b,int &x,int &y){
    if(!b){x=1;y=0;return a;}
    int Gcd=Exgcd(b,a%b,x,y);
    int t=x;
    x=y;y=t-a/b*y;
    return Gcd; 
}
signed main() {
   n=read();int Mul=1;
   for(int i=1;i<=n;i++){
       M[i]=read();Mul*=M[i];Y[i]=read();
   }
   for(int i=1;i<=n;i++){
       int qwq=Mul/M[i];
       int x=0,y=0;
       Exgcd(qwq,M[i],x,y);
       Ans+=Y[i]*qwq*(x>=0?x:x+M[i]);
   }
   return print(Ans%Mul),0;
}

套式子来就行,注意变量别混了就行。

扩展中国剩余定理(Extended Chinese remainder theorem,EXCRT)

鸣谢扩展中国剩余定理讲解-Yang1208

鸣谢扩展中国剩余定理详解-自为风月马前卒

我们知道中国剩余定理用来求解同于方程组必须要求模数互质,但是如果某个啥币出题不让他们互质呢?

自为风月马前卒:“把出题人吊起来干一顿。”

CRTEXCRT 其实没多少关系,一个用 Exgcd ,另一个是构造。

先列出这一把子方程 {xx1(modm1)xx2(modm2)xx3(modm3)

我们选择上面俩看看能不能合成,于是得到下面一个方程组 {x=x1+k1×m1x=x2+k2×m2

我们的到了一个等式:x1+k1×m1=x2+k2×m2 ,移项得到 k1×m1+(k2)×m2=x2x1,是不是 ax+by=c 的形式?自然阔欧搞上,我们用扩欧求出 k1 的通项,但是根据扩欧的限制条件,必须有gcd(m1,m2)(x2x1) ,如果前提不满足,则这个同余方程组无解。我们设 K1K2K1×m1+(K2)×m2=gcd(m1,m2)的两个特解,将式子两边都乘上 x2x1gcd(m1,m2),就知道上述式子 k1=K1×x2x1gcd(m1,m2)k2=K2×x2x1gcd(m1,m2),带回去,得到:

{x=x1+K1×x2x1gcd(m1,m2)×m1x=x2+K2×x2x1gcd(m1,m2)×m2

显然满足这个方程组的K1K2不只一组,并且每一组K1K2都对应一个 x,所以我们能知道每两个解Δ就是 (x2x1)gcd(m1mod2)×m1(x2x1)gcd(m1m2)×m2的倍数,所以 Δ 一定是 m1×m2gcd(m1m2) 的倍数,即 Δlcm(m1m2) 的倍数。

感谢梓苏的讲解。为什么呢,设有 K1K1 ,带入一式,得到两式作差,Δx=(k1k1)×(x2x1)gcd(mod1mod2)×m1 ,得到 Δ(x2x1)gcd(mod1mod2)×m1的倍数,同理得到 Δ 也是 (x2x1)gcd(m1m2)×m2 的倍数。

所以每两个解 Δ 一定是m1×m2gcd(m1m2)的倍数,那m1×m2gcd(m1m2)就是lcm(m1,m2),所以 Δ 一定是 lcm(m1,m2) 的倍数。

又因为 x=k1×m1+x1,这样我们就将上面两个同余方程合成为 xk1×m1+x1(modlcm(m1m2))

完事,

费马小定理

内容:若 p 为质数, gcd(a,p)=1 ,则ap11(modp)

证明自行百度,其实是我不会。

徐佬给出了解释,我们来看他怎么说:image-20220126220751616

图在PDF里。

欧拉定理

实质上是对费马小定理的拓展。

内容:若正整数 a,p 互质,则 aφ(n)1(modn)

证明自行百度,梓苏也不会了。,给个Link欧拉-费马小定理定理(定理证明)

推论:若 a,n 互质,则对于任意正整数 b ,有 ababmodφ(n)modn

证明一下,设 b=q×φ(n)+r0rφ(n),则 r=bmodφ(n)前方高能

ab=aqφ(n)+r(aφ(n))q×ar1q×ararabmodφ(n)(modn)

这式子很明白了吧。

扩展欧拉定理:

ababmodφ(n)+φ(n)(modn),当 a,n 不一定互质且 bφ(n)

abab(modn),当 a,n 不一定互质且 b<φ(n)

证明详解这里,我太菜了,不会证,梓苏说记住就行?

【数论数学】扩展欧拉定理一扶苏一

附赠一个小推论:

推论:若正整数 an 互质,则满足 ax1(modn) 的最小正整数 x0φ(n) 的约数

欧拉函数

定义:1N 中与 N 互质数的个数叫欧拉函数,记 φ(N)

N 进行质因数分解 N=p1c1×p2c2××pkck

则有 φ(N)=N×(11p1)×(11p2)××(11pk)

特别的φ(1)=1

证明:要求的就是 1N 中与 N 不含相同质因子的数,我们先假设 N 只有两个质因子,假设 pqN 的质因子,那么 1Np 的倍数有Np,同理 qNq 个,我们自然要筛掉这些数,但是其中 q×p 被筛了两次,所以还要加回来,得 NNpNq+Npq,对式子稍作变换,得 N×(11p1q1pq),再变得 N×(11p)×(11q),然后我们采用数学归纳法类推到多项就得到上面式子。

实现:

①求单个欧拉函数,类似质数判断

根据上面函数定义式,可以得到一个在分解质因数的同时求解单个欧拉函数的方法,时间复杂度 O(n)

int Get_phi(int x){
    int res=x;
    for(int i=2;i*i<=x;i++)
    if(!(x%i)){res=res/i*(i-1);while(!(x%i)) x/=i;}
    if(x>1) res=res/x*(x-1);
    return res;
}

②递推打表,类似埃式筛

void Phi(int n){
    for(int i=1;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);
    }
}

③线性筛,类似欧拉筛质数

需要用到欧拉函数的两个性质

若有 pN,且满足 p2N,则 φ(N)=φ(Np)×p.

证明:若有 pN,且满足 p2N,说明 NN/p 有相同的质因子,我们分析只含两个质因子的简单情况,

φ(N)=NNpNq+Npqφ(N/p)=NpNp2Npq+Np2q,二者相除商为 p

若有 pN,且一定不满足 p2N,则 φ(N)=φ(Np)×(p1).

证明:若有 pN,且满足 p2N,说明 NN/p 一定互质,根据积性函数定义有 φ(N)=φ(N/p)×φ(p),因为 p 为质数,则 φ(p)=p1(费马小定理),得φ(N)=φ(Np)×(p1),证毕。

void Phi(int n){ phi[1]=1;
    for(int i=2;i<=n;i++){
        if(!vis[i]) Prime[++cnt]=i,phi[i]=i-1;
        for(int j=1;j<=cnt&&i*Prime[j]<=n;j++){
            vis[i*Prime[j]]=true;
            if(!(i%Prime[j])){ phi[i*Prime[j]]=phi[i]*Prime[j];}
            //说明i*Prime[j]中含有两个Prime[j]的因子,应用推论1
            else phi[i*Prime[j]]=phi[i]*phi[Prime[j]];//反之推论2
        }
    }
}

组合数

组合数-BlackDan

再推销一波博客(✿◡‿◡)

多重集合的排列

M=k1a1,k2a2,knanai 为不同元素, ki 为个数。

多重集合 M={k1a1,k2a2,,knan}r 排列数为 kr

多重集合 M={k1a1,k2a2,,knan}的全排列数为:(k1+k2++kn)!k1!k2!kn!

多重集合部分有限部分无限分母仅除有限部分阶乘乘。

一个例子:在 1n 之间随机生成长度为 n 的整数序列,请问正好含有 n1 个不同的整数的方案数,答案mod1e9+7

Ans=Cnn1×(n1)×n!2!mod1e9+7

先从 n 个数里面选 n1 个数,对于剩下一个位置可以是这 n1 个数的任意一个,n 个数随便排列,但是有两个重复元素,注意对 2! 求逆元。

二项式定理

定理:(a+b)n=r=0nCnranrbr

这就是二项式定理,等式右边即为 (a+b)n 的二项式,共有 n+1 项。

Cnranrbr 叫做二项式展开式的第 r+1 项,也就是通项,通项用 Tr+1 表示。

Tr+1=CnranrbrCnr(t=0,1,2n) 叫做 r+1 项的二项式系数。

证明:组合证明法

将幂次拆开, (a+b)n=(a+b)(a+b)(a+b)

按照乘法分配律展开,直到无括号。因为每项都可以选 s 或者 b ,因此共有 2n 项,显然所有项都是anrbr(r=0,1,2n) 的形式,为了计数形如anrbr 的项的系数,必须从 na+b 中选取 nra (从而乘机中其余的 r 个项都是 b),所以 anrbr 的系数是 Cnnr=Cnr,证毕。

P1313:二项式定理,快速幂,费马小定理,逆元

卢卡斯定理(Lucas's theorem)

对于非负整数 m,n 和质数 pCmni=0kCmini(modp)

m=mkpk++m1p+m0n=nkpk++n1p+n0m,np 进制展开。

但其实我们常用这个可以与之互推的式子:

Cmn=CmmodpnmodpCmpnp(modp),当 m<n 时,规定 Cmn=0

我们可以利用这个式子递归求解,递归边界就是 n=0。其实只需要记住公式就够了,因为你可以马上写 出卢卡斯的板子。

int C(int m,int n,int p){
	return m<n?0:fact[m]*inv(fact[m],p)%p*inv(fact[m-n],p)%p;
}
int lucas(int m,int n,int p){
	return !n?1:lucas(m/p,n/p,p)*C(m%p,n%p,p)%p;
}

证明:设 x是任意小于 p 的正整数,那么:Cpx=p!x!(px)!=p(p1)!x(x1)!(px)!=pxCp1x1,由于 x<pp 是质数,所以存在 xp 意义下的逆元,故:Cpxpinv(x)Cp1x1(modp),显然右边是 p 的倍数,所以 Cpx0(modp),由二项式定理:(1+x)n=i=0nCnixi,由于 (1+x)p=i=0pCpi 除了 i=0i=p 的项外模 p 都为零(上面已证),所以 (1+x)p1+xp(modp),现在我们设 {mp=qmnp=qn{mmodp=rmnmodp=rn,那么那么 {m=qmp+rmn=qnp+rn,再由二项式定理 (a+b)m=k=0mCmkxk(咱也不知道为啥这句话不显示),而同时有(前方高能):(1+x)m=(1+x)qmp+rm=(1+x)qmp(1+x)rm=[(1+x)p]qm(1+x)rm (1+xp)qm(1+x)rm=i=0qmCqmixipj=0rmCrmjxj=i=0qmj=0rmCqmiCrmjxip+j(modp)
注意满足 j>mr 的项为 0,所以上面和式一定遍历所有可能的非零项,我们再枚举 k=ip+j,得到 (1+x)mk=0mCqmk/pCqmkmodpxk(modp),为什么呢?和梓苏讨论了一会,是这样的:i=0qmj=0rm 能使 ip+j 遍历到的范围是 0qmp+rm=m ,即换元之后枚举的 k=0m,根据二项式定理的结果,得 k=0mCmkxkk=0mCqmk/pCqmkmodpxk(modp),对比系数,则,CmkCqmkpCrmkmodp=CqmqkCrmrk(modp),令 k=n,得到 Cmn=CmmodpnmodpCmpnp(modp),定理得证。

扩展卢卡斯定理

扩展卢卡斯定理-OI Wiki

自行解决,我累了。

后记

经过这几天的经历,充分的告诉了我一个事实:只有交了钱的自学最有效率!

这金牌真tm ssh??

本文作者:Gym_nastics

本文链接:https://www.cnblogs.com/BlackDan/p/15848308.html

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

posted @   Gym_nastics  阅读(164)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起