1. 程式人生 > 實用技巧 >複習:數論

複習:數論

目錄

質數

判斷質數

考慮一個數\(x\),其一定能分解成\(a*b\)的形式,這裡只需要保證\(a\)\(b\)都為整數即可,

顯然的,\(min(a,b)\le \sqrt{x}\),所以只需要列舉\([2,\sqrt x]\)即可

bool pd(int x)
{
    for(int i=2;i*i<=x;i++)
        if(x%i==0)
            return 0;
    return 1;
}

區間內的質數

埃氏篩法

一個自然數集合

考慮到質數的因數只有\(1\)和他本身,所以考慮對每一個數,將其在集合中的所有的倍數都刪去,沒有被刪去的數即為質數,時間複雜度即為\(\sum_{i=1}^{n}\frac{n}{i}=n*log_n\)(調和級數求和),也可以看做每個數被篩了多少次

bool vis[MAXN+5];
int pri[MAXN],lenp;
void sieve(int n)
{
    for(int i=2;i<=n;i++)
    {
        if(vis[i]==0)
        {
            pri[++lenp]=i;
            for(int j=i;1ll*i*j<=n;j++)
                vis[i*j]=1;
        }
    }
}

尤拉篩

考慮在埃氏篩上進行改進,為什麼埃氏篩會帶一個log,因為其會被其所有的質因數都篩一次

我們對其進行一些限制,每一個數只能被其最小的質因數篩去

考慮目前的質數集合為\(P\),我們列舉其的倍數\(a\)

從小到大列舉\(P\)中的元素

如果\(a\%p_i==0\),那麼比\(p_i\)大的元素可以不用列舉,設\(a=k*p_i\),那麼\(a*p_{i+1}=p_i*k*p_{i+1}\),根據我們所規定的限制,那麼\(a*p_{i+1}\)一定會被\(p_i\)篩去,

bool vis[MAXN+5];
int pri[MAXN],lenp;
void sieve(int n)
{
    for(int i=2;i<=n;i++)
    {
        if(vis[i]==0)
            pri[++lenp]=i;
        for(int j=1;j<=lenp&&1ll*i*pri[j]<=n;j++)
        {
            vis[i*pri[j]]=1;
            if(i%pri[j]==0)
                break;
        }
    }
}

最大公約數和最小公倍數

輾轉相除法

內容

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

證明

\(gcd(a,b)=p\),那麼\(\begin{cases}a=x*p\\b=y*p\end{cases}\)\(a\%b=(x*p)\%(y*p)=x\%y*p\)

\(b\)\(a\%b\)的最大公約數依然為\(p\)

實現

其實可以直接用\(algorithm\)庫中的__gcd

int gcd(int a,int b)
{
    if(b==0)
        return a;
    return gcd(b,a%b); 
}

裴蜀定理

內容

如果有\(gcd(a,b)=d\),且有\(c|d\),那麼一定有整數\(x,y\),滿足\(ax+by=c\)

證明

如果有\(ax+by=c\),那麼一定有\(ax*\frac{d}{c}+by*\frac{d}{c}=d\),設\(x'=x*\frac{d}{c},y'=y*\frac{d}{c}\),此時的\(x'和y'\)一定都為整數,那麼\(ax'+by'=d\),因為\(gcd(a,b)=d\),所以有\(\frac{a}{d}x'+\frac{b}{d}y'=1\)。同樣的,設\(a'=\frac{a}{d},b'=\frac{b}{d}\),所以\(a'x'+b'y'=1\)

我們要證明的既可以轉換為:對於一對\(a,b\),滿足\(gcd(a,b)=1\),一定有整數\(x,y\),滿足\(ax+by=1\)

引理1

如果有\(gcd(a,b)=1\),那麼不存在一個小於b的正整數k,使得\(k*a\equiv 0\pmod b\)

反證法,

如果存在一個\(k\)使得\(k*a\equiv 0 \pmod b\),那麼\(k*a\)中一定有\(b\)的所有質因數,但同時\(a\)沒有任何一個\(b\)的質因數,所以\(k\)一定包含\(b\)的所有質因數,即\(k\ge b\),矛盾,所以引理得證

推論

在相同的條件下,\(0*a\%b,1*a\%b\ldots(b-1)*a\%b\),這些數一定都不一樣

反證法,

\(i*a\equiv j*a\pmod b,同時0<i<j<b\),那麼一定有\(a*(j-i)\equiv 0 \pmod b\)

根據引理1,\(j-i\ge b\),顯然這是矛盾的

引理2

如果有\(gcd(a,b)=1\),必然存在一個整數\(k\),使得\(k*a\%b=1\)

根據推論,對於\(0*a\%b,1*a\%b\ldots(b-1)*a\%b\),這些數一定不一樣,但是某一個數取模\(b\)的結果一定在\([0,b-1]\),但是同時根據推論,我們已經可以得到\(b\)個兩兩不相同的數,所以k一定存在

再來考慮如果有\(gcd(a,b)=1\),那麼一定有\(x*a\%b=1\),所以定然有\(ax-by=1\),所以有\(ax+by=1\),即裴蜀定理得證

同餘等價系,剩餘系,縮系

對於一個正整數\(p\),對於\(a\%p\),只可能有\(p\)種結果,並且屬於\([0,p-1]\)

\(p\)的剩餘系記作\(Z_p\),即小於\(p\)的所有非負整數

同餘等價類,

考慮在模\(p\)的剩餘系下,只有\(p\)種結果,所以每一個數都代表了\(\%p=a\)的所有數,對於\(a\)相同的數,我們稱其為同餘等價類

如果只考慮\(gcd(i,p)=1\)的元素,便得到一個子集,稱這個子集為縮系,記作\(Z^*_p\)

尤拉函式

內容

\(p\)得縮系的大小,記作\(\phi(p)\)

如果\(p\)為質數,那麼\(\phi(p)=p-1\)

如果\(n=p^q\),這裡的\(p\)為質數,那麼\(\phi(n)=p^q-p^{q-1}=p^q*(1-\frac{1}{p})\)

同時尤拉函式是一個積性函式證明

所以\(\phi(n)=n*\prod_{p_i|n,並且p_i為質數}(1-\frac{1}{p_i})\)

求單個\(\phi\)

直接套用公式即可

int phi(int n)
{
    int ret=n;
    for(int i=2;1ll*i*i<=n;i++)
    {
        if(n%i==0)
        {
            ret=ret/i*(i-1);
            while(n%i==0)
                n=n/i;
        }
    }
    if(n>1)
        ret=ret/n*(n-1);
    return ret;
}

求區間每個數的\(\phi\)

因為\(\phi\)為積性函式,所以只需要改進一下埃氏篩法即可,

當然也可以改尤拉篩,但是改後的時間複雜度變成了\(O(n*log_n)\)可能是筆者太菜,想不到更好的改法

void sieve(int n)
{
    for(int i=1;i<=n;i++)
        s[i]=i;
    for(int i=2;i<=n;i++)
    {
        if(vis[i]==0)
        {
            for(int j=1;1ll*i*j<=n;j++)
            {
                vis[i*j]=1;
                s[i*j]=s[i*j]/i*(i-1);
            }
        }
    }
}

尤拉定理

內容

如果有\(gcd(a,p)=1\),那麼有\(a^{\phi(p)}\%p=1\)

證明

\(p\)的縮係為\(\{p_1,p_2,\ldots,p_n\}\),因為\(gcd(a,p)=1\),所以\(\{a*p_1\%p,a*p_2\%p,\ldots,a*p_n\%p\}\)同樣也是\(p\)的縮系

所以有\(\sum_{i=1}^{n}p_i\%p=\sum_{i=1}^{n}a*p_i\%p=\sum_{i=1}^{n}p_i\%p*a^{\phi(p)}\%p\)

\(a^{\phi(p)}\%p=1\)

拓展尤拉定理

內容

\(a,m\)為正整數,當\(r>\phi(m)\),有\(a^r\equiv a^{r\%\phi(m)+\phi(m)}\pmod m\)

證明

考慮如果\(gcd(a,m)=1\),這個結論顯然成立

所以討論\(gcd(a,m)\neq1\)的情況

引理1

如果有\(\begin{cases}x\equiv y\pmod n\\x\equiv y\pmod m\end{cases}\),那麼有\(x\equiv y \pmod {lcm(n,m)}\)

比較明顯?

\(\begin{cases}x-y\equiv 0\pmod n\\x-y\equiv 0 \pmod m\end{cases}\rightarrow x-y\equiv 0 \pmod {lcm(n,m)}\rightarrow x\equiv y \pmod {lcm(n,m)}\)

引理2

如果\(p\)為質數,\(\phi(p^q)\ge q\)

顯然的\(gcd(p^i-1,p^1)==1\),並且\(i\in [1,q]\),所以\(\phi(p^q)\ge q\)

引理3

如果\(m=p^q\)\(p\)為質數,那麼有\(a^r\equiv a^{r\%\phi(m)+\phi(m)}\equiv 0\pmod m\)

因為\((a,m)>1\),則\(a\)必然有因數\(p\)

因為\(r>\phi(m)\ge q\),所以有\(a^r=x*p^r=y*p^{\phi(m)}=z*p^{q}\)

因為\(r>q\),所以\(a^r\equiv 0 \pmod m\)

因為\(\phi(m)\ge q\),所以\(r\%\phi(m)+\phi(m)\ge q\),所以\(a^{r\%\phi(m)+\phi(m)}\equiv 0\pmod m\)

所以\(a^r\equiv a^{r\%\phi(m)+\phi(m)}\equiv 0\pmod m\)

現在考慮\(m=\prod p_i^{q_i}\)

\(m_i=p_i^{q_i}\)

顯然,對於每一個\(m_i\)

如果\(gcd(a,m_i)=1\),則根據尤拉定理可以得到\(a^r\equiv a^{r\%\phi(m)+\phi(m)}\pmod {m_i}\)

如果\(gcd(a,m_i)>1\),則根據引理3有\(a^r\equiv a^{r\%\phi(m)+\phi(m)}\pmod {m_i}\)

因為尤拉函式是一個積性函式並且\(m_i\)之間兩兩互質,所以\(\phi(m)=\prod \phi(m_i)\)

根據引理1可以得

\(a^r\equiv a^{r\%\phi(m)+\phi(m)}\pmod m\)

逆元

當整數\(a*b\equiv 1 \pmod p\),我們稱\(b\)為a的逆元,記作\(b=a^{-1}\)

只有\(a\)\(p\)互質的情況下,\(a\)才有逆元

費馬定理

內容

如果\(p\)為質數,且\(a\%p\neq 0\),則有\(a^{p-1}\%p=1\)

證明

考慮到裴蜀定理的推論,對於\(i\in[1,p-1]\)\(gcd(i*a,p)\)一定是互質的,

即有\(\sum_{i=1}^{p-1}i*a\%p=\sum_{i=1}^{p-1}i\%p\)

又知道\(\sum_{i=1}^{p-1}i*a\%p=a^{p-1}\%p*\sum_{i=1}^{p-1}i\%p\)

即有\(a^{p-1}\%p=1\)

威爾遜定理

內容

\((p-1)!\equiv -1\pmod p\),當且僅當\(p\)為質數,其中\((p-1)!=\prod_{i=1}^{p-1}i\)

證明

充分性

\(p\)為質數\(\rightarrow (p-1)!\equiv -1 \pmod p\)

因為\(i\in [1,p-1]\),且\(p\)為質數,所以一定有\(gcd(i,p)=1\),根據裴蜀定理的引理2,一定存在\(j*a\%p=1\)\(j\in[1,p-1]\),同時,根據裴蜀定理的引理1,\(i\)只有1個逆元,

再者,我們考慮\(j=i\)的情況

\(i^2\%p=1\rightarrow i^2-1=kp\)

\((i-1)(i+1)=kp\),同時\(p\)為質數,且\(i\in[1,p-1]\)

\(i=1,p-1\)

即除了1和p-1,其他數都有一個唯一的逆元,同時我們根據尤拉定理$a^{-1}\equiv a^{p-2}\pmod p $,再根據裴蜀定理的引理1,每個數的逆元都是不一樣的(反證法)

所以一定有$(p-1)!\equiv -1 \pmod p $

必要性

\((p-1)!\equiv -1 \pmod p \rightarrow\) \(p\)為質數

\(p|(p-1)!+1\)

假設\(p\)不是質數,且\(a\)\(p\)的質因子

那麼一定有\(a|(p-1)!+1\)

但是同時,因為\(a\)\(p\)的一個質因子,所以一定有\(a|(p-1)!\)

但同時\(gcd((p-1)!+1,(p-1)!)=1\),故\(a\)只可能為1,

與假設矛盾,所以不成立,即命題得證

拓展歐幾里得

內容

求不定方程\(ax+by=c\),其中\(a,b,c\)已知,\(gcd(a,b)|c\)

如果我們已知方程\(ax+by=gcd(a,b)\),那麼\(ax+by=c\)也就是在原來的基礎上乘上\(\frac{c}{gcd(a,b)}\)

\(\begin{aligned}ax+by&=gcd(a,b)\\&=gcd(b,a\%b)\\&=bx'+(a\%b)y'\\&=bx'+(a-b*\lfloor\frac{a}{b}\rfloor)y'\\&=ay'+b(x'-y'\lfloor\frac{a}{b}\rfloor)\end{aligned}\)

\(\begin{cases}x=y'\\y=x'-y'\lfloor\frac{a}{b}\rfloor\end{cases}\)

考慮一直遞迴下去,則一定會出現\(gcd(a,0)=a\)的情況

即此時\(\begin{cases}x=1\\y=0\end{cases}\)

實現

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

單個逆元

內容

\(p\)為質數的情況下

根據費馬定理\(a^{p-1}\equiv 1\pmod p\),所以\(a^{p-2}\equiv a^{-1}\pmod p\)

如果\(p\)不是質數

考慮對\(ax\%p=1\),那麼就一定有\(ax-py=1\),設\(y'=-y\),則有\(ax+py'=1\)

這裡因為\(a\)\(p\)互質,所以方程一定有解,通過拓展歐幾里得演算法即可求出\(x\)

實現

不會有人連快速冪都不會吧,不會吧不會吧

int qkpow(int a,int b)
{
    if(b==0)
        return 1;
    if(b==1)
        return a;
    long long t=qkpow(a,b/2);
    t=t*t%mod;
    if(b%2==1)
        t=t*a%mod;
    return t;
}

區間逆元

遞推式

關於逆元,有一個很巧妙的遞推式

\(f(i)\)表示\(i\)在模\(m\)意義下的逆元

邊界條件即為\(f(1)=1\)

那麼\(f(n)=(-f(m\%n)*(m/n)\%m+m)\%m\)

證明

我們設\(m=k*i+r\)\(k=\lfloor\frac{p}{m}\rfloor,r=m\%n\)

那麼\(k*i+r\equiv 0\pmod m\)

那麼有\((k*i+r)*i^{-1}*r^{-1}\equiv 0*i^{-1}*r^{-1}\pmod m\)

\(k*r^{-1}+i^{-1}\equiv 0\pmod m\)

\(k*r^{-1}\equiv -i^{-1}\pmod m\)

\(-k*r^{-1}\equiv i^{-1}\pmod m\)

即遞推式得證

中國剩餘定理

求解方程組\(\begin{cases}x\equiv a_1\pmod {r_1}\\x\equiv a_2\pmod {r_2}\\\dots\\x\equiv a_n\pmod {r_n}\end{cases}\)保證\(r_i\)兩兩互質

我們設\(A_i=\prod_{j=1}^n r_j[i\neq j]\),因為\(r_i\)之間兩兩互質,所以\(gcd(A_i,r_i)=1\),所以必然存在\(c_i*A_i\%r_i=1\)(裴蜀定理的引理2),設\(x_i=a_i*A_i*c_i\),則\(x_i\%r_i=a_i\),且\(x_i\%r_j=0(i\neq j)\)

所以最後的\(x=\sum_{i=1}^{n}a_i*A_i*c_i\%r\)

通解的話就相當與\(x+\prod_{i=1}^nr_i\)

long long crt()
{
    long long s=1,x=0;
    for(int i=1;i<=n;i++)
        s=s*r[i];
    for(int i=1;i<=n;i++)
        x=(x+(a[i]*(s/r[i])%s*inv(s/r[i],r[i]))%s)%s;
    return x;
}