hdu 5901 count prime & code vs 3223 素数密度
hdu5901题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5901
code vs 3223题目链接:http://codevs.cn/problem/3223/
思路:主要是用了一个Meisell-Lehmer算法模板,复杂度O(n^(2/3))。讲道理,我不是很懂(瞎说什么大实话....),下面输出请自己改
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 typedef long long LL; 6 const LL N = 5e6 + 2; 7 bool np[N]; 8 int prime[N], pi[N]; 9 10 int getprime() { 11 int cnt = 0; 12 np[0] = np[1] = true; 13 pi[0] = pi[1] = 0; 14 for(int i = 2; i < N; ++i) { 15 if(!np[i]) prime[++cnt] = i; 16 pi[i] = cnt; 17 for(int j = 1; j <= cnt && i * prime[j] < N; ++j) { 18 np[i * prime[j]] = true; 19 if(i % prime[j] == 0) break; 20 } 21 } 22 return cnt; 23 } 24 const int M = 7; 25 const int PM = 2 * 3 * 5 * 7 * 11 * 13 * 17; 26 int phi[PM + 1][M + 1], sz[M + 1]; 27 void init() { 28 getprime(); 29 sz[0] = 1; 30 for(int i = 0; i <= PM; ++i) phi[i][0] = i; 31 for(int i = 1; i <= M; ++i) { 32 sz[i] = prime[i] * sz[i - 1]; 33 for(int j = 1; j <= PM; ++j) { 34 phi[j][i] = phi[j][i - 1] - phi[j / prime[i]][i - 1]; 35 } 36 } 37 } 38 int sqrt2(LL x) { 39 LL r = (LL)sqrt(x - 0.1); 40 while(r * r <= x) ++r; 41 return int(r - 1); 42 } 43 int sqrt3(LL x) { 44 LL r = (LL)cbrt(x - 0.1); 45 while(r * r * r <= x) ++r; 46 return int(r - 1); 47 } 48 LL getphi(LL x, int s) { 49 if(s == 0) return x; 50 if(s <= M) return phi[x % sz[s]][s] + (x / sz[s]) * phi[sz[s]][s]; 51 if(x <= prime[s]*prime[s]) return pi[x] - s + 1; 52 if(x <= prime[s]*prime[s]*prime[s] && x < N) { 53 int s2x = pi[sqrt2(x)]; 54 LL ans = pi[x] - (s2x + s - 2) * (s2x - s + 1) / 2; 55 for(int i = s + 1; i <= s2x; ++i) { 56 ans += pi[x / prime[i]]; 57 } 58 return ans; 59 } 60 return getphi(x, s - 1) - getphi(x / prime[s], s - 1); 61 } 62 LL getpi(LL x) { 63 if(x < N) return pi[x]; 64 LL ans = getphi(x, pi[sqrt3(x)]) + pi[sqrt3(x)] - 1; 65 for(int i = pi[sqrt3(x)] + 1, ed = pi[sqrt2(x)]; i <= ed; ++i) { 66 ans -= getpi(x / prime[i]) - i + 1; 67 } 68 return ans; 69 } 70 LL lehmer_pi(LL x) { 71 if(x < N) return pi[x]; 72 int a = (int)lehmer_pi(sqrt2(sqrt2(x))); 73 int b = (int)lehmer_pi(sqrt2(x)); 74 int c = (int)lehmer_pi(sqrt3(x)); 75 LL sum = getphi(x, a) + LL(b + a - 2) * (b - a + 1) / 2; 76 for (int i = a + 1; i <= b; i++) { 77 LL w = x / prime[i]; 78 sum -= lehmer_pi(w); 79 if (i > c) continue; 80 LL lim = lehmer_pi(sqrt2(w)); 81 for (int j = i; j <= lim; j++) { 82 sum -= lehmer_pi(w / prime[j]) - (j - 1); 83 } 84 } 85 return sum; 86 } 87 88 int main() { 89 init(); 90 LL n,m; 91 while(cin >> m >> n) 92 { 93 cout<<prime[n]<<endl; //输出第n个素数 94 cout<<pi[m]<<endl; //输出该数是第几个素数 95 cout << lehmer_pi(n) <<endl; //输出区间[1,n]包含的素数 96 cout << lehmer_pi(n)-lehmer_pi(m) << endl; //判断区间(m,n]包含的素数 97 98 cout << lehmer_pi(n)-lehmer_pi(m-1) << endl; //输出区间[m,n]包含的素数个数 99 101 102 } 103 return 0; 104 }
还有一个O(n^(4/3))算法,我又不懂,菜的抠脚....
1 #include <bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 ll f[340000],g[340000],n; 5 void init(){ 6 ll i,j,m; 7 for(m=1;m*m<=n;++m)f[m]=n/m-1; 8 for(i=1;i<=m;++i)g[i]=i-1; 9 for(i=2;i<=m;++i){ 10 if(g[i]==g[i-1])continue; 11 for(j=1;j<=min(m-1,n/i/i);++j){ 12 if(i*j<m)f[j]-=f[i*j]-g[i-1]; 13 else f[j]-=g[n/i/j]-g[i-1]; 14 } 15 for(j=m;j>=i*i;--j)g[j]-=g[j/i]-g[i-1]; 16 } 17 } 18 int main(){ 19 while(scanf("%I64d",&n)!=EOF){ 20 init(); 21 cout<<f[1]<<endl; 22 } 23 return 0; 24 }