埃氏筛法
#define exp 2.7182818285
#define Y 0.57721566490153286060651209
#define ln2 0.69314718055995
#define ln3 1.0986122886681
#define lg2 0.301029995663981
#define lg5 0.698970004336018
#define ln5 1.6094379124341
int prime[N];
void pre()
{
memset(prime,1,sizeof(prime));prime[1]=0;
for(int i=2;i<N;i++)
{
if(prime[i])
for(int j=2*i;j<N;j+=i)prime[j]=0;
}
}
线性筛
int p[MAX],cnt;
bool isprime[MAX];
void prime()
{
cnt=1;
memset(isprime,1,sizeof(isprime));//初始化认为所有数都为素数
isprime[0]=isprime[1]=0;//0和1不是素数
for(int i=2;i<MAX;i++)
{
if(isprime[i])
p[cnt++]=i;//保存素数i
for(int j=1;j<cnt&&p[j]*i<MAX;j++)
{
isprime[p[j]*i]=0;
If(i%isprimep[j]=0)break;
//筛掉小于等于i的素数和i的积构成的合数
}
}
}
Meisell-Lehmer
//求n以内的素数个数
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 5*1e6 + 2;
bool np[N];
int prime[N], pi[N];
int getprime() {
int cnt = 0;
np[0] = np[1] = true;
pi[0] = pi[1] = 0;
for(int i = 2; i < N; ++i) {
if(!np[i]) prime[++cnt] = i;
pi[i] = cnt;
for(int j = 1; j <= cnt && i * prime[j] < N; ++j) {
np[i * prime[j]] = true;
if(i % prime[j] == 0) break;
}
}
return cnt;
}
const int M = 7;
const int PM = 2 * 3 * 5 * 7 * 11 * 13 * 17;
int phi[PM + 1][M + 1], sz[M + 1];
void init() {
getprime();
sz[0] = 1;
for(int i = 0; i <= PM; ++i) phi[i][0] = i;
for(int i = 1; i <= M; ++i) {
sz[i] = prime[i] * sz[i - 1];
for(int j = 1; j <= PM; ++j) {
phi[j][i] = phi[j][i - 1] - phi[j / prime[i]][i - 1];
}
}
}
int sqrt2(LL x) {
LL r = (LL)sqrt(x - 0.1);
while(r * r <= x) ++r;
return int(r - 1);
}
int sqrt3(LL x) {
LL r = (LL)cbrt(x - 0.1);
while(r * r * r <= x) ++r;
return int(r - 1);
}
LL getphi(LL x, int s) {
if(s == 0) return x;
if(s <= M) return phi[x % sz[s]][s] + (x / sz[s]) * phi[sz[s]][s];
if(x <= prime[s]*prime[s]) return pi[x] - s + 1;
if(x <= prime[s]*prime[s]*prime[s] && x < N) {
int s2x = pi[sqrt2(x)];
LL ans = pi[x] - (s2x + s - 2) * (s2x - s + 1) / 2;
for(int i = s + 1; i <= s2x; ++i) {
ans += pi[x / prime[i]];
}
return ans;
}
return getphi(x, s - 1) - getphi(x / prime[s], s - 1);
}
LL getpi(LL x) {
if(x < N) return pi[x];
LL ans = getphi(x, pi[sqrt3(x)]) + pi[sqrt3(x)] - 1;
for(int i = pi[sqrt3(x)] + 1, ed = pi[sqrt2(x)]; i <= ed; ++i) {
ans -= getpi(x / prime[i]) - i + 1;
}
return ans;
}
LL lehmer_pi(LL x) {
if(x < N) return pi[x];
int a = (int)lehmer_pi(sqrt2(sqrt2(x)));
int b = (int)lehmer_pi(sqrt2(x));
int c = (int)lehmer_pi(sqrt3(x));
LL sum = getphi(x, a) + LL(b + a - 2) * (b - a + 1) / 2;
for (int i = a + 1; i <= b; i++) {
LL w = x / prime[i];
sum -= lehmer_pi(w);
if (i > c) continue;
LL lim = lehmer_pi(sqrt2(w));
for (int j = i; j <= lim; j++) {
sum -= lehmer_pi(w / prime[j]) - (j - 1);
}
}
return sum;
}
int main() {
init();
LL n;
while(cin >> n) {
cout << lehmer_pi(n) << endl;
}
}
Min_25 prime<n
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#define M 5333333
using namespace std;
typedef long long ll;
ll A[M], B[M];
double inv[M];
int main() {
ll n;
scanf("%lld", &n);
int lim = sqrt(n) + 1;
if(n <= 10) return printf("%d\n", (n >= 2) + (n >= 3) + (n >= 5) + (n >= 7)), 0;
for(int i = 1; i <= lim; i++) inv[i] = 1.0/ (i * 2 - 1), A[i] = (n / (i * 2 - 1) + 1) / 2, B[i] = (i + 1) / 2 - (i == 1);
for(int i = 3; i <= lim; i += 2)if(B[i] != B[i - 1]) {
unsigned l = B[i - 1];
for(int j = 1; i * (j * 2 - 1) <= lim; j++) A[j] -= A[i * j - (i - 1) / 2] - l;
double tmp = n / i;
for(int j = (lim / i + 1) / 2 + 1, s = min(n / i / i, (ll) lim); j * 2 - 1 <= s; j++) A[j] -= B[(int) (tmp * inv[j] + 1e-7)] - l;
for(int j = lim / i; j >= i; j--)
for(int k = i - 1; k >= 0; k--) B[j * i + k] -= B[j] - l;
}
printf("%lld\n", A[1]);
return 0;
}
Miller-rabin
//判断n是否为素数
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
using namespace std;
const int times = 20;
int number = 0;
//map<long long, int>m;
long long Random( long long n ) //生成[ 0 , n ]的随机数
{
return ((double)rand( ) / RAND_MAX*n + 0.5);
}
long long q_mul( long long a, long long b, long long mod ) //快速计算 (a*b) % mod
{
long long ans = 0;
while(b)
{
if(b & 1)
{
b--;
ans =(ans+ a)%mod;
}
b /= 2;
a = (a + a) % mod;
}
return ans;
}
long long q_pow( long long a, long long b, long long mod ) //快速计算 (a^b) % mod
{
long long ans = 1;
while(b)
{
if(b & 1)
{
ans = q_mul( ans, a, mod );
}
b /= 2;
a = q_mul( a, a, mod );
}
return ans;
}
bool witness( long long a, long long n )//miller_rabin算法的精华
{//用检验算子a来检验n是不是素数
long long tem = n - 1;
int j = 0;
while(tem % 2 == 0)
{
tem /= 2;
j++;
}
//将n-1拆分为a^r * s
long long x = q_pow( a, tem, n ); //得到a^r mod n
if(x == 1 || x == n - 1) return true; //余数为1则为素数
while(j--) //否则试验条件2看是否有满足的 j
{
x = q_mul( x, x, n );
if(x == n - 1) return true;
}
return false;
}
bool miller_rabin( long long n ) //检验n是否是素数
{
if(n == 2)
return true;
if(n < 2 || n % 2 == 0)
return false; //如果是2则是素数,如果<2或者是>2的偶数则不是素数
for(int i = 1; i <= times; i++) //做times次随机检验
{
long long a = Random( n - 2 ) + 1; //得到随机检验算子 a
if(!witness( a, n )) //用a检验n是否是素数
return false;
}
return true;
}
main( )
{
int t;cin>>t;
while(t--)
{
long long n;scanf("%lld",&n);
if(miller_rabin(n))
{
puts("Prime");continue;
}
else puts("NO");
}
}
©著作权归作者所有:来自51CTO博客作者qinXpeng的原创作品,如需转载,请注明出处,否则将追究法律责任
共同学习,写下你的评论
评论加载中...
作者其他优质文章