质数
定义:
若一个大于1的数的因数只有1和它本身,那么称该数为质数(素数),否则称其为合数。
素数分布定理
设\(x≥1\),以\(π(x)\)表示不超过\(x\)的素数的个数,当\(x→∞\)时,\(π(x)~x/ln(x)\)。
质数的判定(试除法)
定理:
若一个数\(N\)为合数,则\(N\)必存在一个大于 \(1\) 小于等于\(\sqrt N\)的因数。
证明:假设\(N\)不存在小于等于\(\sqrt N\)的因数。
按定义,\(N\)至少存在一个大于1小于\(N\)的因数,记该数为\(a\).
那么 \(N = a * x\),其中\(x = N / a\)。
若\(a\)和\(x\)均大于\(\sqrt N\),那么$ a * x > N$,与前面矛盾,故假设不成立。
bool is_prime(int n) { if (n < 2) return false; int k = sqrt(n); for (int i = 2; i <= k; i++) if (n % i == 0) return false; return true; }
例1.
房间里面有\(N\)盏关着的灯,编号依次为\(1,2, 3,。。。,N\),有\(N\)个人,他们的编号也依次为\(1,2, 3,。。。,N\),现这\(N\)个人依次走入房间,每人将编号为自己编号倍数的灯的开关按钮按下一次,这样灯的熄亮状态就会切换一次。在这\(N\)个人完成他们的操作后,输出最后亮着的灯。
质数的筛法
埃氏筛法
原理:任意整数 \(x\) 的倍数 \(2x\) , \(3x\) , ...均是合数。
prime[1] = 1; for (int i = 2; i <= n; i++) { for (int k = 2; k <= n / i; k++) prime[k * i] = 1; }
时间复杂度 \(O(n\log(n))\)
优化1. 在筛\(x\)的倍数的时候,可以只考虑质数,因为若x是合数,那么数可以被比\(x\)更小的质因数筛掉。
优化2. 在筛质数x的倍数的时候,可以从\(x^2\)开始考虑,因为小于\(x^2\)的x的倍数会被更小的质数筛掉。
prime[1] = 1; for (int i = 2; i <= n; i++) { if (prime[i]) continue; // 优化1 for (int k = i; k <= n / i; k++) // 优化2 prime[k * i] = 1; }
时间复杂度 \(O(n\log \log n)\)
线性筛法
原理:保证每个合数仅被其最小的合数筛掉一次。
bool vis[1000]; int prime[10000]; int cnt = 0; for (int i = 2; i <= n; i++) { if (!vis[i]) prime[++cnt] = i; for (int j = 1; j <= cnt && i <= n / prime[j]; j++) { vis[i * prime[j]] = 1; if (i % prime[j] == 0) break; } }
质因数分解
算术基本定理
任何一个大于1的正整数都能唯一分解为有限个质数的乘积,可写作:
\[N=p_1^{c_1}p_2^{c_2}...p_m^{c_m}\]
其中\(c_i\)都是正整数,\(p_i\)都是质数,且满足\(p_1 < p_2 <... < p_m\)。
试除法
void divide (int n) { m = 0; int sq = sqrt(n); for (int i = 2; i <= sq; i++) { if (n % i == 0) { p[++m] = i, c[m] = 0; while (n % i == 0) c[m]++; } } if (n > 1) p[++m] = n, c[m] = 1 }
时间复杂度\(O(\sqrt n)\)
例2
给定两个整数L和U,你需要在闭区间\([L,U]\)内找到距离最接近的两个相邻质数\(C_1\)和\(C_2\)(即\(C_2-C_1\)是最小的),如果存在相同距离的其他相邻质数对,则输出第一对。
同时,你还需要找到距离最远的两个相邻质数\(D_1\)和\(D_2\)(即\(D_1-D_2\)是最大的),如果存在相同距离的其他相邻质数对,则输出第一对。
数据范围:
\(1≤L<U≤2^{31}−1\)
其中\(L\)和\(U\)的差值不会超过1000000
时空限制:
1s / 64MB
例3
给定整数\(N\) ,试把阶乘\(N!\)分解质因数,按照算术基本定理的形式输出分解结果中的\(p_i\) 和 \(c_i\) 即可。
输入格式
一个整数\(N\)。
输出格式
\(N!\) 分解质因数后的结果,共若干行,每行一对\(p_i\), \(c_i\),表示含有\(p_i^{c_i}\)项。按照\(p_i\)从小到大的顺序输出。
数据范围
\(1≤N≤10^6\)
例4
给定整数\(N\) ,试求出阶乘\(N!\)末尾 \(0\) 的个数。
来源:https://www.cnblogs.com/keik/p/12448561.html