质数又称做素数.
质数是除了1和自己没有其余因数的数.
与之相反的是合数.
1不属于质数或合数.函数
假设咱们要判断\(n\)是否是质数.
从2枚举\(n-1\),若能整除\(n\),\(n\)就不是质数.
时间复杂度\(O(n)\).
但因数是成对的(除了\(\sqrt n\))
令\(n=c_1 c_2\),假设\(c_1 \le c_2\)
则\(c_1 \le \sqrt n , c_2 \ge \sqrt n\)
因此只需枚举到\(\sqrt n\).spa
bool isprime(long long x) { for(int i=2; i<=sqrt(x); i++) { if(x%i==0) return false; } return true; }
时间复杂度\(O(\sqrt n)\).code
如今咱们要求\(1\)到\(n\)中所有质数.class
最简单的办法就是判断每一个数是否为质数.
时间复杂度\(O(n \sqrt n)\).im
从\(1\)到\(\sqrt n\),若这个数没有被标记,即为质数.
只要发现了一个质数\(t\),就把从\(1\)到\(n\)中所有\(t\)的倍数标记.
时间复杂度\(O(n \log n)\)时间
对于每一个\(i(1<i<n)\),筛去全部小于\(i\)的质数与\(i\)的乘积.
不难发现,有些合数被重复筛去.
设全部小于\(i\)的质数分别为\(p_1,p_2,...,p_j\).
当\(i\)%\(p_k=0\)时,中止筛\(i\)的倍数,便可避免重复.
由于当\(l>k\)时,全部\(i*p_l\)都会被比\(i\)大的数与\(p_k\)的乘积筛去.vi
for(int i=2;i<=n;i++){ if(!vis[i]) { cnt++; pri[cnt]=i; } for(int j=1;i*pri[j]<=n;j++){ vis[i*pri[j]]=true; if(i%pri[j]==0) break; } }
时间复杂度\(O(n)\)while
一个数的质因数一定小于等于\(\sqrt n\).
只需把\(i\)从\(2\)枚举到\(\sqrt n\),从\(n\)中去掉全部\(i\)并作记录,就能求出\(n\)的质因数.co
for(int i=2;i<=sqrt(n);i++) { while(n%i==0) { n/=i; cnt[i]++; } }
时间复杂度\(O(\sqrt n)\)block
欧拉函数是从\(1\)到\(n-1\)的数中与\(n\)互质的数的个数.
1.对于质数\(n\),\(φ(n)=n-1\).
2.对于质数\(p\),\(φ(p^k)=(p-1)*p^{k-1}\).
hasn't finished