一、基本的思想和定理。
算數基本定理,也叫唯一分解定理。指的是乙個大於一的合數都可以分解為有限個質數相乘。即n=p1
a1p2
a2*.....*pn
an。p即為質數,a為質數的指數。
二、一些重要的公式。
1、求約數個數和約數的和。
給定一正整數n,求n的所有約數的個數。公式:num=(a1+1)*(a2+1)*......*(an+1)。至於原理,我理解的思路是,按照組合原則,p1
a1一共有(a1+1)種情況,其餘的以此類推。
2、求約數個數的和。
給定乙個正整數n,求n的所有約數之和。公式:sum=(1+p1
1+p1
2+.....+p1
n)*(1+p2
1+p2
2+.....+p2
n)*......*(1+pn
1+pn
2+...+pn
n)。原理就是,把n的約數和分解為pa的約數和。
3、尤拉函式。
φ(n)表示為某乙個正整數的尤拉函式:小於n的正整數中和n互質的正整數的個數。
尤拉函式具有以下三個特性:
// 1、φ(n)=n*(1-1/p1)*(1-1/p2 )*(1-1/p3)*.....*(1-1/pn);
// 2、若m為質數,n%m==0,則φ(m*n)=m*φ(n);
// 3、若m,n互質,則φ(n*m)=φ(m)*φ(n)。
三、c++**。
1、如何判斷素數。
// 常規的方法是判斷n是否能被2到n之間的數整除,如果能夠整除,則說明n有除了1以外的其他因數,則n不是質數。
優化後的思路是:假如存在乙個數(不一定為正整數)i,使得i*i=n,則我們可以從2到i之間的數進行判斷,因為兩個數之間成反比關係,乙個肯定大於等於i,另乙個肯定小於等於i。那麼,只要保證在2到i之間沒有正整數可以整除n,我們就可以知道,n一定為質數。
bool is_prime(intn) }
return
true
;}
2、如何分解質因數。
// 分解質因數首先從最小的質數開始分解,如果能夠被整除,則一直迴圈到不能被整除為止,在此期間還可以計算質因數出現的次數。
同樣也可以進行優化,和如何判斷質數的優化方法一樣,如果有這樣的數i,我們就可以在<=i處提前判斷完成,因為在判斷前面的質數之後,大於i的部分不可能會有質數再被整除。
除非當我們整除這些質數之後的n,本身就是乙個比較大的質數,這時候,我們可以在最後判斷n是否大於1,是的話,n即為質數。比如1004=2^2*251。在我們列舉2之後,n的值就變成了251,這時候從3到sqrt(251,1/2)之間都沒有數整除n。
vectorint,int>>v;int prime_factorization(int
n));}}
}if(n>1
)); }
}
// 如果對動態陣列不熟悉,可以嘗試用結構來構建。
3、篩選素數之埃式篩選法(e_sieve)
// 埃式篩選的原理也很簡單,在我們找到乙個素數之後,素數的倍數一定不是素數。根據這一原則,我們就可以進行篩選了。
優化的地方和上面一樣,首先是找素數的過程,到i處就可以了。然後是在素數的倍數方面,當i=5時,2*5,3*5,4*5已經在前面優化過了。這時候從5*5開始篩選就可以了。
時間複雜度o(nloglogn)
intprimes[maxx];
bool
vis[maxx];
void e_sieve(int
n) }
}}
4、篩選素數之線性篩(linear_sieve)
// 線性篩主要是針對埃篩的一些問題進行解決,以使得時間複雜度降低。埃篩的主要問題是乙個數可以被兩個質數篩選。即使是優化後的**。比如12被2和3兩個質數篩選。
優化方面會有一些難懂。推薦先記憶模板,再慢慢理解。
優化的地方在:我們在篩選的時候,讓合數被最小質因數篩選。加乙個判定條件就可以了。
時間複雜度o(n)
intprimes[maxx];
bool
vis[maxx];
void
linear_sieve(int n)
for (int j = 0; primes[j] * i <= n;j++)}}
}
對於第二個for迴圈裡的if語句,就是說,如果i可以整除primes[j],那麼primes[j+1]一定不是primes[j+1】*i的最小質因數。比如i=2,primes[0]=2;2%2=0,下乙個質數為3,而2*3的最小質因數為2,因此break;
// 可以自己手動列式子理解一下。
5、篩選素數之尤拉篩。//放到後面去講
6、求所有約數
// 和找質因數一樣的道理。
vectorv;void divisor_find(int
n) }
}}
7、求所有約數的個數。
// 根據公式求就可以了。分解質因數記錄質數的指數。
intcnt[maxx];
int k = 0
;int number_of_divisor(int
n) cnt[k++] =s;}}
int sum = 0
;
for (int i = 0; i < k;i++)
return
sum;
}
8、求所有約數的和。
// 一樣的道理,根據公式求即可。不過要注意的是,可能會用到費馬小定理。但是這裡我們還是要注意乙個公式就是x/y%mod可以轉換為x%(y*mod)/y;
ll quickpow(ll a,ll b)b >>= 1
; a = (a *a);
}return
res;
}int
a[maxx], b[maxx];
int k = 0
;int sum_of_divisor(int
n) a[k] =i;
b[k] =s;
k++;}}
if(n>1
)
intsum;
for (int i = 0; i < k;i++)
return
sum;
}
9、尤拉函式
// n*(i-1/p)可以換成n/p*(p-1)。然後按公式寫就可以了。
int euler_function(intn) }
}if(n>1
)
return
res;
}
10、尤拉篩
// 根據尤拉函式三個特性寫
intprimes[maxx], phi[maxx];
bool
vis[maxx];
void
euler_sieve()
for (int j = 0; primes[j] * i <= n;j++)
else}}
}
C 知識點總結複習
c 1 c 是靜態型別語言,使用靜態型別的程式語言是在編譯時執行型別檢查,而不是在執行時執行型別檢查。2 物件導向程式設計 c 完全支援物件導向的程式設計,包括物件導向開發的四大特性 3 基礎語法 a.c 是區分大小寫的程式語言 b.三字元組就是用於表示另乙個字元的三個字串行,又稱為三字串行。三字串...
C 複習小知識點總結
一 c 純虛函式和抽象類詳解 1 在c 中,可以將虛函式宣告為純虛函式,語法格式為 virtual 返回值型別 函式名 函式引數 0 最後的 0並不表示函式返回值為0,它只起形式上的作用,告訴編譯系統 這是純虛函式 包含純虛函式的類稱為抽象類 抽象類通常是作為基類,讓派生類去實現純虛函式。派生類必須...
模組知識點總結及複習
模組的概述 1.在python中,乙個擴充套件名為.py的檔案都是乙個模組 2.把有特定功能的 放在乙個檔案中作為乙個模組,從而方便其他程式和指令碼的匯入並使用。另外也可以避免函式名與變數名衝突 3.提高 的可維護性 4.提高 的可重用性 自定義模組 作用 規範 讓 更易閱讀 方便其他程式設計師使用...