zoukankan      html  css  js  c++  java
  • HDU 5901 Count primes (模板题)

    题意:给求 1 - n 区间内的素数个数,n <= 1e11。

    析:模板题。

    代码如下:

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include <cstdio>
    #include <string>
    #include <cstdlib>
    #include <cmath>
    #include <iostream>
    #include <cstring>
    #include <set>
    #include <queue>
    #include <algorithm>
    #include <vector>
    #include <map>
    #include <cctype>
    #include <cmath>
    #include <stack>
    #include <tr1/unordered_map>
    #define freopenr freopen("in.txt", "r", stdin)
    #define freopenw freopen("out.txt", "w", stdout)
    using namespace std;
    using namespace std :: tr1;
    
    typedef long long LL;
    typedef pair<int, int> P;
    const int INF = 0x3f3f3f3f;
    const double inf = 0x3f3f3f3f3f3f;
    const LL LNF = 0x3f3f3f3f3f3f;
    const double PI = acos(-1.0);
    const double eps = 1e-8;
    const int maxn = 1e5 + 5;
    const int mod = 1e9 + 7;
    const int N = 1e6 + 5;
    const int dr[] = {-1, 0, 1, 0};
    const int dc[] = {0, 1, 0, -1};
    const char *Hex[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
    int n, m;
    const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    inline int Min(int a, int b){ return a < b ? a : b; }
    inline int Max(int a, int b){ return a > b ? a : b; }
    inline LL Min(LL a, LL b){ return a < b ? a : b; }
    inline LL Max(LL a, LL b){ return a > b ? a : b; }
    inline bool is_in(int r, int c){
        return r >= 0 && r < n && c >= 0 && c < m;
    }
    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(scanf("%I64d", &n) == 1){
            printf("%I64d
    ", lehmer_pi(n));
        }
        return 0;
    }
    
  • 相关阅读:
    leetcode5 Longest Palindromic Substring
    leetcode17 Letter Combinations of a Phone Number
    leetcode13 Roman to Integer
    leetcode14 Longest Common Prefix
    leetcode20 Valid Parentheses
    leetcode392 Is Subsequence
    leetcode121 Best Time to Buy and Sell Stock
    leetcode198 House Robber
    leetcode746 Min Cost Climbing Stairs
    tomcat下使用druid配置jnid数据源
  • 原文地址:https://www.cnblogs.com/dwtfukgv/p/5884723.html
Copyright © 2011-2022 走看看