code and comments
#include <cstdio>
#include <iostream>
#include <vector>
#include <map>
using namespace std;
typedef long long ll;
/**
* 素性测试O(√n)
* 假设输入都是正数
*/
bool is_prime(int n){
for(int i=2;i*i<=n;i++){
if(n%i==0){
return false;
}
}
return n!=1;
}
/**
* 约数枚举O(√n)
*/
vector<int> divisor(int n){
vector<int> res;
for(int i=1;i*i<=n;i++){
if(n%i==0){
//加入前半部分素数
res.push_back(i);
if(i!=n/i){
//加入后半部分素数
res.push_back(n/i);
}
}
}
}
/**
* 整数分解O(√n)
*/
map<int,int> prime_factor(int n){
map<int,int> res;
for(int i=2;i*i<=n;i++){
//如果n是合数
while(n%i==0){
//从2开始统计每一个素数因子的个数
++res[i];
n/=i;
}
}
if(n!=1){
res[n]=1;
}
return res;
}
int main(void){
map<int,int> m=prime_factor(24);
map<int,int>::iterator ite=m.begin();
while(ite!=m.end()){
cout << "因子" << ite->first << "的个数是" << ite->second << endl;
ite++;
}
}
#include <cstdio>
#include <iostream>
using namespace std;
#define MAX_N 100000000
typedef long long ll;
/**
* 保存素数
*/
int prime[MAX_N];
/*
* 标记is_prime[i]是否是素数,用于模拟删除
*/
bool is_prime[MAX_N+1];
/**
* 区间筛法大数组[a,b)
*/
bool is_prime_large[MAX_N];
/**
* 区间筛法小数组[2,√b)
*/
bool is_prime_small[MAX_N];
/**
* 素数筛法返回n以内素数的个数,并将素数保存在prime数组中
*/
int sieve(int n){
//素数个数
int p=0;
//初始化
for(int i=0;i<=n;i++){
is_prime[i]=true;
}
//0,1不是素数,删去
is_prime[0]=is_prime[1]=0;
//遍历
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)内的素数个数
* 先分别做好[2,√b)的表和[a,b)的表,然后从[2,√b)的表中筛得素数的同时,
* 也将其倍数从[a,b)的表中划去,最后剩下的就是[a,b)内的素数了
*/
ll 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_large[i]=true;
}
for(int i=2;(ll)i*i<b;i++){
if(is_prime_small[i]){
//筛[2,√b)
for(int j=2*i;(ll)j*j<b;j+=i){
is_prime_small[j]=false;
}
//筛[a,b)
//(a+i-1)/i)*i是符合>=a且是i的倍数的最小的数
//因为除以i会舍弃掉余数,所以再加i保证不会小于应有的数,而减1则保证除以i之后不会比应有的数大1
for(ll j=max(2LL,(a+i-1)/i)*i;j<b;j+=i){
is_prime_large[j-a]=false;
}
}
}
ll k=0;
for(ll i=0;i<b-a;i++){
if(is_prime_large[i]){
k++;
}
}
return k;
}
int main(void){
//int num=sieve(100);
ll a=22801763489;
ll b=22801787297;
ll num=segment_sieve(a,b);
cout << num << endl;
}