日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数论入门笔记

發布時間:2023/12/31 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数论入门笔记 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

數論入門筆記


目錄

  • 數論入門筆記
  • 一、 數論是什么
  • 二、數論基礎
      • 1. 歐幾里德算法(輾轉相除法)
      • 2. 有關素數的基礎算法
        • 單個整數素性測試
            • 簡單素數篩
        • 多個整數素性測試
          • 埃氏篩法(Eratosthenes篩法)
            • 區間篩法
            • 歐拉篩法(線性篩法)
      • 3. 擴展歐幾里德算法
    • 三. 模運算
    • 四. 快速冪運算
      • 反復平方法
  • 五、計數與概率
    • 1. 楊輝三角與二項式
    • 2. 數論中的計數問題
    • 3. 離散概率初步


一、 數論是什么

數論主要研究整數的性質。需要關注的是一些特殊的數,如質數,素數,最大公約數,最小公倍數等等,以及相應的歐幾里得算法,和各種篩法,歐拉函數,積性函數等等等等。。。。。。。


二、數論基礎

1. 歐幾里德算法(輾轉相除法)

可以通過歐幾里得算法來算出兩個正整數a,b的最大公約數。
復雜度:O(log(max(a,b))O(log(max(a,b))O(log(max(a,b))
代碼如下(示例):

int gcd(int a, int b){return b == 0? a : gcd(b,a%b);//b==0 是遞歸的邊界條件}

下面是該程序的運算過程:

也可以直接調用庫函數__gcd(a,b);

2. 有關素數的基礎算法

單個整數素性測試

簡單素數篩

素數只有:素數它本身和1。判斷一個數是否是素數只需檢查 2 ~ /(n)\sqrt(n)(?n)內的整數是否存在有能整除這個數的數就能判斷這個數是不是素數。
復雜度:O((n))O(\sqrt(n))O((?n))
代碼如下(示例):

bool is_prime() {for(int i=2;i*i<=n;i++){if(n%i==0)return false;}return n!=1; }

多個整數素性測試

n內的素數的總數大概是n/ln(n)n/ln(n)n/ln(n)

埃氏篩法(Eratosthenes篩法)

用于高效去對多個整數進行素數檢測(素數的個數<= 10610^6106)
2 ~ n的數寫入數組,之后找到最小并且沒有被劃去的數,之后將在2 ~ n之間這個數的倍數劃去,以此枚舉n以內的素數。
復雜度:O(nlog(log(n)))O(nlog(log(n)))O(nlog(log(n)))
代碼如下(示例):

#define MAX_N 1000010 int prime[MAX_N]; bool is_prime[MAX_N+1]; int sieve(int n) {int p=0;for(int i=0;i<=n;i++) is_prime[i]=true;is_prime[0]=is_prime[1]=false;for(int i=2;i<=n;i++){if(is_prime[i]){prime[p++]=i;for(int j=2*i;j<=n;j+=i)is_prime[j]=false;}}return p; }
區間篩法

在區間[a,b)上 (a<b<=101210^{12}1012,b-a<=10610^6106)
用埃氏篩法算出[2,(b)\sqrt(b)(?b)]的質數,同時劃去[a,b)中這個質數的倍數。
代碼如下(示例):

#define MAX_L 1000010 #define MAX_SQRT_B 1000010 typedef long long int ll; bool is_prime[MAX_L]; bool is_prime_small[MAX_SQRT_B]; void segment_sieve(ll a,ll b){for(int i=0;(ll)i*i<b;i++)is_prime_small[i]=true;for(int i=0;i<b-a;i++)is_prime[i]=true;for(int i=2;(ll)i*i<b;i++){if(is_prime_small[i]){for(int j=2*i;(ll)j*j<b;j+=i){is_prime_small[j]=false;}for(ll j=i*max(2LL,(a+i-1)/i);j<b;j+=i)is_prime[j]=false;}} }
歐拉篩法(線性篩法)

埃氏篩法在篩選時有重復,如6它被素數2和素數3都篩過,像這樣的數有很多,而歐拉篩法不會。

int prime[maxn]; int is_prime[maxn]; void Prime(){mem(is_prime,0);mem(prime, 0);for (int i = 2;i <= maxn; i++) {if (!is_prime[i]) {prime[++prime[0]] = i; //紀錄素數, 這個prime[0] 相當于 cnt,用來計數}for (int j = 1; j <=prime[0] && i*prime[j] <= maxn; j++) {is_prime[i*prime[j]] = 1;if (i % prime[j] == 0) {break;}}} }

3. 擴展歐幾里德算法

裴蜀定理
若a,b是整數,且gcd(a,b)=g,那么對于任意的整數x,y,ax+by=m中的m一定是g的倍數。反之ax+by=m有解,m一定是g的倍數。
它的一個重要推論是:a,b互質的充要條件是存在整數x,y使ax+by=1。

擴展歐幾里德算法這個算法原理如下:
gcd(a,b)=gcd(b,amodb);gcd(a,b)=gcd(b,a mod b);gcda,b=gcd(b,amodb);
gcd(a,b)=ax1+by1(裴蜀定理)gcd(a,b)=ax_1+by_1(裴蜀定理)gcd(a,b)=ax1?+by1?()
即gcd(b,amodb)=bx2+(amodb)y2即gcd(b,a mod b)=bx_2+(a mod b)y_2gcdb,amodb=bx2?+(amodb)y2?
推導通解:
ax1+by1=ax2+by2ax_1+by_1=ax_2+by_2ax1?+by1?=ax2?+by2?
即ax1+ax2=by1+by2即ax_1+ax_2=by_1+by_2ax1?+ax2?=by1?+by2?
兩邊同除gcd(a,b),簡寫g兩邊同除gcd(a,b),簡寫ggcd(a,b),g//如果g=0,意味a=0 or b=0
(a/g)(x1+x2)=(b/g)(y1+y2),有因為互素,所以(x1+x2)一定是(b/g)的倍數,所以可的通解為(x0+k(b/g),y0+k(b/g))(a/g)(x_1+x_2)=(b/g)(y_1+y_2),有因為互素,所以(x_1+x_2)一定是(b/g)的倍數,所以可的通解為(x_0+k(b/g),y_0+k(b/g))(a/g)(x1?+x2?)=(b/g)(y1?+y2?),(x1?+x2?)b/gx0?+k(b/g),y0?+k(b/g)
推導算法:
ax1+by1=bx2+(amodb)y2ax_1+by_1=bx_2+(amodb)y_2ax1?+by1?=bx2?+(amodb)y2?
已知x2,y2,amodb=a?(a/b)?b,代入已知x_2,y_2,amodb=a-(a/b)*b,代入x2?,y2?,amodb=a?(a/b)?b,
ax1+by1=bx2+(a?(a/b)?b)y2=ax_1+by_1=bx_2+(a-(a/b)*b)y_2=ax1?+by1?=bx2?+(a?(a/b)?b)y2?=
ax1+by1=ay2+b(x2?(a/b)y2)ax_1+by_1=ay_2+b(x_2-(a/b)y_2)ax1?+by1?=ay2?+b(x2??(a/b)y2?)
x1=y2,y1=(x2?(a/b)y2)x_1=y_2,y_1=(x_2-(a/b)y_2)x1?=y2?,y1?=(x2??(a/b)y2?)
當b=0時ax+by=gcd(a,0)=a;?>x=1,y=0;當 b=0時 ax+by=gcd(a,0)=a; ->x=1,y=0;b=0ax+by=gcd(a,0)=a;?>x=1,y=0;//臨界條件

//1. void gcd(int a,int b,int& d,int& x,int& y) {if(!b){d=a;x=1;y=0;}else {gcd(b,a%b,d,y,x);y-=x*(a/b);} } //2. int extgcd(int a,int b,int &x,int &y)//擴展歐幾里得算法 {int d=a;if(b!=0){d=extgcd(b,a%b,x,y);y-=(a/b)*x;}else{x=1;y=0;}return d; }

費馬小定理
如果p是一個質數,而整數a不是p的倍數,則有ap?1≡1(modp)a^{p-1}≡1(mod p)ap?11(modp
逆元
類似倒數,ax≡bmodm;ac≡1modmax≡b mod m; ac≡1 mod maxbmodm;ac1modm; c就是a的逆元; ac≡1modm等價ac=1+mkac≡1 mod m等價ac=1+mkac1modmac=1+mk ac-mk=1,這就成了 擴展歐幾里德算法。

int mod_inverse(int a,int b) {int x, y;extgcd(a,m,x,y);return (m+x%m)%m; }

三. 模運算

同余定理:
a mod b=c 則(a+b*k) mod b=c (k!=0)
(a+b) mod n=[(a mode n)+(b mod n)] mod n
(a-b) mod n=[(a mode n)-(b mod n)+n] mod n
a b mod n=(a mod n)(b mod n) mod n
注意乘法時可能會溢出所以要用long long int來保存中間結果
代碼如下(示例):

int mul_mod(int a,int b,int mod) {a%=mod;b%=mod;return (int)(a*1LL*b)%mod;}

四. 快速冪運算

反復平方法

xn=((x2)2)...\ x^ {n}=((x^{2})^2)...?xn=(x2)2)...
復雜度:O(log(n))O(log(n))O(log(n))

代碼如下(示例):

typedef long long int ll; ll mod_pow(ll x,ll n,ll mod) {ll res = 1;while(n>0){if(n&1) res=res * x % mod;//當n為奇數時x=x*x%mod;n>>=1;}return res; }

五、計數與概率

1. 楊輝三角與二項式

C[i][j]=C[i?1][j?1]+C[i?1][j]C[i][j]=C[i-1][j-1]+C[i-1][j]C[i][j]=C[i?1][j?1]+C[i?1][j]

2. 數論中的計數問題

n的正約數的個數(a1+1)(a2+1)..(an+1)(a1+1)(a2+1)..(an+1)(a1+1)(a2+1)..(an+1)
歐拉篩法求1-n的k次方的約數個數之和

const int size=1e7+5; bool prime[size];//is素數 int p[size];//素數 int sigma[size];//因質數個數 int tot=0;//素數個數 int k;//素數k次方 void init() {sigma[1]=1;for(int i=2;i<size;i++) prime[i]=true;for(int i=2;i<size;i++){if(prime[i]) {p[tot++]=i;sigma[i]=k+1;}for(int j=0;j<tot&&p[j]*i<size;j++){prime[i*p[j]]=false;if(i%p[j]==0){sigma[i*p[j]]=sigma[i]*2-sigma[i/p[j]];// 相當于break;}else {sigma[i*p[j]]=sigma[i]*(k+1);// 相當于}}} }

算小于與n互素的整數個數用歐拉函數。
φφφ函數的值:

φ(x)=x(1?1/p(1))(1?1/p(2))(1?1/p(3))…..(1?1/p(n))φ(x)=x(1-1/p(1))(1-1/p(2))(1-1/p(3))…..(1-1/p(n))φ(x)=x(1?1/p(1))(1?1/p(2))(1?1/p(3))..(1?1/p(n)) 其中p(1),p(2)…p(n)p(1),p(2)…p(n)p(1),p(2)p(n)為x的所有質因數;x是正整數; φ(1)=1φ(1)=1φ(1)=1(唯一和1互質的數,且小于等于1)。注意:每種質因數只有一個。

3. 離散概率初步

條件概率:P(B∣A)=P(AB)/P(A)P(B|A)=P(AB)/P(A)PBA=P(AB)/P(A)
全概率公式:P(B)=P(A1)P(B∣A1)+P(A2)P(B∣A2)+..P(B)=P(A1)P(B|A1)+P(A2)P(B|A2)+..PB=P(A1)P(BA1)+P(A2)P(BA2)+..

總結

以上是生活随笔為你收集整理的数论入门笔记的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。