质数判定
1.试除法
bool is_prime(int n) {
if (n < 2) return false;
for (int i = 2; i <= sqrt(n); i++)
if (n % i == 0)return false;
return true;
}
质数的筛选
Eratosthenes筛法
求出1~n的所有质数
void primes(int n) {
memset(v, 0, sizeof(v));//合数标记
for (int i = 2; i <= n; i++) {
if (v[i])continue;
for (int j = i; j <= n / i; j++)
v[i * j] = 1;
}
}
质因数分解
算术基本定理:
N=
p
1
c
1
{p1}^{c1}
p1c1
p
2
c
2
{p2}^{c2}
p2c2…
p
m
c
m
{pm}^{cm}
pmcm
其中ci都是正整数,pi都是质数,且满足p1<p2<…<pm.
试除法
void divide(int n) {
m = 0;
for (int i = 2; i <= sqrt(n); i++) {
if (n % i == 0) {
p[++m] = i, c[m] = 0;
while (n % i == 0)c[m]++, n /= i;
}
}
if (n > 1)p[++m] = n, c[m] = 1;
for (int i = 1; i <= m; i++)cout << p[i] << "^" << c[i] << " ";
}
例题1:Prime Distance
链接:
ACWING196
给定两个整数 L 和 U,你需要在闭区间 [L,U] 内找到距离最接近的两个相邻质数 C1 和 C2(即 C2−C1 是最小的),如果存在相同距离的其他相邻质数对,则输出第一对。
同时,你还需要找到距离最远的两个相邻质数 D1 和 D2(即 D1−D2 是最大的),如果存在相同距离的其他相邻质数对,则输出第一对。
输入格式
每行输入两个整数 L 和 U,其中 L 和 U 的差值不会超过 106。
输出格式
对于每个 L 和 U,输出一个结果,结果占一行。
结果包括距离最近的相邻质数对和距离最远的相邻质数对。(具体格式参照样例)
如果 L 和 U 之间不存在质数对,则输出 There are no adjacent primes.。
数据范围
1≤L<U≤231−1
输入样例:
2 17
14 17
输出样例:
2,3 are closest, 7,11 are most distant.
There are no adjacent primes.
代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
const int MAXN=1000001,INF=2147483647;
int primes[MAXN];
bool notPrime[MAXN];
int primeCnt=0;
void initPrime(){
for(int i=2;i<=sqrt(INF);i++){
if(notPrime[i])continue;
primes[++primeCnt]=i;
for(int j=i;j<=sqrt(INF)/i;j++){
notPrime[i*j]=1;
}
}
}
int newPrimes[MAXN];
int main(){
initPrime();
int l,r;
while(cin>>l>>r){
memset(notPrime,0,sizeof(notPrime));
if(l==1)notPrime[0]=1;
for(int i=1;i<=primeCnt;i++){
for(int j=l/primes[i];j<=r/primes[i];j++){
if(j>1)notPrime[primes[i]*j-l]=1;
}
}
int newPrimeCnt=0;
for(int i=l;i<=r;i++){
if(!notPrime[i-l])newPrimes[++newPrimeCnt]=i;
if(i==r)break;
}
int minDelta=INF,maxDelta=0;
int minX1,minX2,maxX1,maxX2;
for(int i=1;i<newPrimeCnt;i++){
int nowDelta=newPrimes[i+1]-newPrimes[i];
if(nowDelta<minDelta){
minDelta=nowDelta;
minX1=newPrimes[i],minX2=newPrimes[i+1];
}
if(nowDelta>maxDelta){
maxDelta=nowDelta;
maxX1=newPrimes[i],maxX2=newPrimes[i+1];
}
}
if(minDelta==INF)printf("There are no adjacent primes.\n");//
else printf("%d,%d are closest, %d,%d are most distant.\n",minX1,minX2,maxX1,maxX2);
}
return 0;
}
例题2:阶乘分解
给定整数 N,试把阶乘 N! 分解质因数,按照算术基本定理的形式输出分解结果中的 pi 和 ci 即可。
输入格式
一个整数 N。
输出格式
N! 分解质因数后的结果,共若干行,每行一对 pi,ci,表示含有 pcii 项。按照 pi 从小到大的顺序输出。
数据范围
1≤N≤106
输入样例:
5
输出样例:
2 3
3 1
5 1
样例解释
5!=120=23∗3∗5
AcWing113
公式:
对于每个p,p的个数为:
[
N
P
\frac{N}{P}
PN]+[
N
P
2
\frac{N}{P^2}
P2N]+[
N
P
3
\frac{N}{P^3}
P3N]+……+[
N
p
l
o
g
p
N
\frac{N}{p^{log_pN}}
plogpNN]=
Σ
p
k
<
=
N
\Sigma_{p^k<=N}
Σpk<=N|
N
P
3
\frac{N}{P^3}
P3N|
#include<cstring>
#include<iostream>
using namespace std;
const int maxn = 1e6;
int m, p[maxn],v[maxn];
void primes(int n) {
memset(v, 0, sizeof(v));//合数标记
for (int i = 2; i <= n; i++) {
if (v[i])continue;
for (int j = i; j <= n / i; j++)
v[i * j] = 1;
}
for (int i = 2; i <= n; i++) { if (!v[i])p[++m] = i; }
}
int main()
{
int n;
scanf("%d", &n);
primes(n);
for (int i = 1; i <= m; i++) {
int P = p[i], ans = 0,temp = n;
for (;temp;temp/=P) {
ans += (temp / P);
}
printf("%d %d\n", P, ans);
}
return 0;
}