1. 程式人生 > 實用技巧 >數學基礎:數論

數學基礎:數論

一個基礎的概念:a|b表示a能整除b,b是a的一個因子

裴蜀定理:對任何整數a、b和它們的最大公約數g,a*x+by=m有解時,g|m。藉助拓展歐幾里得演算法,可以求出解。(求逆元常轉化為這個式子)。不只是x和y,當有z1、z2等多個元素時該定理可以進行擴充套件


同餘和剩餘

x≡a(mod m),x和a關於模m同餘;a為x模m的一個剩餘,當0<=a<=m-1時a為最小剩餘


費馬小定理

當p是一個素數時,且a與p互質,有ap-1≡1(mod p)

尤拉定理

當a與n互質時,有aφ(n)≡1(mod p)。尤拉函式是指:對於一個正整數 n ,小於 n 且和 n 互質的正整數(包括 1)的個數,記作 φ(n)

根據公式打出求尤拉函式的如下程式碼:

ll eular(ll n)
{
    ll ans = n;
    for(int i=2; i*i <= n; ++i)
    {
        if(n%i == 0)
        {
            ans = ans/i*(i-1);
            while(n%i == 0)
                n/=i;
        }
    }
    if(n > 1) ans = ans/n*(n-1);    //最後可能還剩一個大素數因子
    return ans;
}

上面的複雜度是O(n^2),可以通過篩法降到O(n*logn)。還可以與尤拉篩結合,在求素數的同時完成求尤拉函式的操作。

inline void work(int n) 
{ 
    for(re int i=1;i<=n;++i) 
    {
        p[i]=i; 
    }
    for(re int i=2;i<=n;++i) 
    { 
        if(p[i]==i)    //如果i是質數
        { 
            for(re int j=i;j<=n;j+=i) 
            { 
                p[j]=p[j]/i*(i-1);     //那麼就把i的所有倍數篩出來 
            } 
        } 
    }
}

又有拓展尤拉公式:

拓展尤拉公式用於處理求ab(mod p),當b沒有什麼特徵的時候。


伯特蘭—切比雪夫定理

若整數n > 3,則至少存在一個質數p,符合n < p < 2n − 2。另一個稍弱說法是:對於所有大於1的整數n,至少存在一個質數p,符合n < p < 2n。

例題洛谷P5535。該定理的一個應用是互質數之間的擴散,所有數都將在1或2次之間完成擴散。


線性同餘方程

線性同餘方程a*x≡b(mod m),可以轉化為線性不定方程a*x+m*y=b。根據裴蜀定理,gcd(a,m)|b時方程有解。對該方程兩邊同除gcd,拓展歐幾里得方法求出一組解。在模n意義下一共有d個解,對求出的解+(n/d)遍歷即可求出所有解。

有一些細節需要值得注意:(1)求出xx後要進行處理,xx=(xx+m)%m (2)此時的xx是與gcd(a,b)對應的解,對於普遍情況,(xx*(g/b))%(m/b) (3)求解的集合,(xx*(g/b))%(m/b)+(m/b)


中國剩餘定理

求解單變數模線性方程組,x≡a1(mod m1),x≡a2(mod m2),......

若m1、m2、...互質則有解。(1)令M=m1*m2*...,並有M1=M/m1,... (2)拓展歐幾里得求t1=M1在m1下的逆元 (3)x=(a1t1M1+a2t2M2+...)%M,在模M意義下有唯一解


無根樹有根樹的計數/Cayley公式/Prufer編碼

一個無向完全圖有nn-2棵生成樹,通俗的說就是n個節點的帶編號的無根樹有nn-2個。

n個節點的度依次為D1, D2, …, Dn的無根樹共有 (n-2)! / [ (D1-1)!(D2-1)!..(Dn-1)! ]個,因為此時Prüfer編碼中的數字i恰好出現Di-1次

令每個已知度數的節點的度數為di,有n個節點,m個節點未知度數,left=(n-2)-(d1-1)-(d2-1)-...-(dk-1)。已知度數的節點可能的組合方式:(n-2)!/(d1-1)!/(d2-1)!/.../(dk-1)!/left!,剩餘left個位置由未知度數的節點隨意填補,方案數為mleft。於是最後有ans=(n-2)!/(d1-1)!/(d2-1)!/.../(dk-1)!/left! * mleft