• SCUT


    https://scut.online/p/142

    但是洲阁筛打表还是超时了,打的表不够长吧,在51nod上面要跑5s。要是快10倍得要密1000倍,根本打不出来(时间意义)。
    暴力check要找的质数是不是要的那个。

    #include<bits/stdc++.h>
    typedef long long ll;
    using namespace std;
    
    const int MAXN = 7500000;
    int n;
    
    int f[MAXN + 5], p[MAXN + 5];
    bool np[MAXN + 5];
    
    ll g(ll n, int m) {
        if(!m)
            return n;
        if(m == 1)
            return n - n / 2;
        if(n <= MAXN) {
            if(f[n] <= m)
                return 1;
            if(f[(int)sqrt(n)] <= m)
                return f[n] - m + 1;
        }
        ll res = g(n, m - 1) - g(n / p[m], m - 1);
        return res;
    }
    
    bool pan(ll x) {
        ll y = sqrt(x);
        return f[y] + g(x, f[y]) - 1 >= n;
    }
    
    void init() {
        for(int i = 2; i <= MAXN; ++i) {
            if(!np[i])
                p[++p[0]] = i;
            for(int j = 1, t; j <= p[0] && (t = p[j] * i) <= MAXN; ++j) {
                np[t] = 1;
                if(i % p[j] == 0)
                    break;
            }
        }
        for(int i = 2; i <= MAXN; ++i)
            f[i] = f[i - 1] + (np[i] == 0);
    
    }
    
    ll pcount[] = {
        373587883,
        776531401,
        1190494759,
        1611623773,
        2038074743,
        2468776129,
        2902958801,
        3340200037,
        3780008329,
        4222234741,
        4666527007,
        5112733757,
        5560695863,
        6010236857,
        6461335109,
        6913774603,
        7367575799,
        7822624247,
        8278737359,
        8736028057,
        9194418049,
        9653704481,
        10113958157,
        10575209467,
        11037271757,
        11500205947,
        11963902331,
        12428375423,
        12893587657,
        13359555403,
        13826206699,
        14293566641,
        14761538761,
        15230122499,
        15699342107,
        16169207209,
        16639648327,
        17110593779,
        17582163853,
        18054236957,
        18526876243,
        18999999247,
        19473535801,
        19947663787,
        20422213579,
        20897216723,
        21372698029,
        21848603809,
        22325014259,
        22801763489
    };
    
    int main() {
    #ifdef Yinku
        freopen("Yinku.in", "r", stdin);
        //freopen("Yinku.out", "w", stdout);
    #endif // Yinku
        init();
        while(~scanf("%d", &n)) {
            int px = n / (int)(2e7);
            ll l = px == 0 ? 1 : pcount[px - 1], r = pcount[px], mid;
            //cout << "l=" << l << " r=" << r << endl;
            while(l < r) {
                mid = (l + r) / 2;
                if(pan(mid))
                    r = mid;
                else
                    l = mid + 1;
            }
            printf("%lld
    ", l);
        }
    }
    

    下面的好迷惑啊;

    #include<iostream>
    #include<cmath>
    #include<assert.h>
    using namespace std;
    typedef long long LINT;
    LINT a,b,goal,n;
    int mark[160000],prime[160000],e,bl[10000005];
    LINT pn(int n)
    {
        LINT s=LINT(n*(log(n)+log(log(n))-1)+n*(log(log(n))-2)/log(n)-6.0*n/1000.0);
        return s<=1?1:s;
    }
    
    inline LINT V2IDX(LINT v, LINT N, LINT Ndr, LINT nv) {
        return v >= Ndr ? (N/v - 1) : (nv - v);
    }
    
    LINT primesum(LINT N) {
        LINT *S;
        LINT *V;
    
        LINT r = (LINT)sqrt(N);
        LINT Ndr = N/r;
    
        assert(r*r <= N and (r+1)*(r+1) > N);
    
        LINT nv = r + Ndr - 1;
    
        V = new LINT[nv];
        S = new LINT[nv];
    
        for (LINT i=0; i<r; i++) {
            V[i] = N/(i+1);
        }
        for (LINT i=r; i<nv; i++) {
            V[i] = V[i-1] - 1;
    
        }
    
        for (LINT i=0; i<nv; i++) {
          //S[i] = V[i] * (V[i] + 1) / 2 - 1;若求素数和,使用此处
            S[i]=V[i] - 1;
          //若求素数个数使用此处
        }
    
        for (LINT p=2; p<=r; p++) {
            if (S[nv-p] > S[nv-p+1]) {
                LINT sp = S[nv-p+1];
                LINT p2 = p*p;
                for (LINT i=0; i<nv; i++) {
                    if (V[i] >= p2) {
                    //S[i] -= p* (S[V2IDX(V[i]/p, N, Ndr, nv)] - sp);若求素数和,使用此处
                        S[i] -= 1* (S[V2IDX(V[i]/p, N, Ndr, nv)] - sp);
                      //若求素数个数,使用此处
                    } else {
                        break;
                    }
                }
            }
        }
    
        return S[0];
    }
    
    int main()
    {
        cin>>n;
        a=pn(n);
        if(a%2&&a>1)a=a-1;//防止预估值本身就是素数的情况,刚开始被这里坑了3个test
        b=a+7000000;
        goal=n-primesum(a);
        for(int i=2;i<=160000;i++)
        {
            if(!mark[i])
            {
                prime[++e]=i;
                for(LINT j=(LINT)i*i;j<=160000;j+=i)
                {
                    mark[j]=1;
                }
            }
        }
        LINT xxx,c;
        for(int i=1;i<=e;i++)
        {
            xxx=(LINT)ceil(1.0*a/prime[i]);
            if(xxx==1) xxx++;
            for(LINT j=xxx;(c=j*prime[i])<b;j++)
            {
                bl[c-a]=1;
            }
        }
        int ans=0;
        c=b-a;
        if(a==1) ans--;
        for(int i=0;i<c;i++)
        {
            if(!bl[i]) ans++;
            if(ans==goal)
            {
                cout<<i+a<<endl;
                break;
            }
        }
        return 0;
    }
    

    Meisell-Lehmer算法 计算2~n之间的素数的个数然后二分就可以了。

    bool np[maxn];  
    int prime[maxn],pi[maxn];  
      
    int getprime()  
    {  
        int cnt=0;  
        np[0]=np[1]=true;  
        pi[0]=pi[1]=0;  
        for(int i=2; i<maxn; ++i)  
        {  
            if(!np[i]) prime[++cnt]=i;  
            pi[i]=cnt;  
            for(int j=1; j<=cnt&&i*prime[j]<maxn; ++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<maxn)  
        {  
            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<maxn) 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<maxn) 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;  
    } 
    
  • 相关阅读:
    Linux内核通杀提权漏洞CVE-2016-5195
    Android APP安全评估工具 Drozer
    (转)手机安全测试
    微信公众号获取的图片不能正常显示的问题
    android开发时gen和bin目录的SVN管理(转)
    处理千万级以上的数据提高查询速度的方法(转)
    Java遍历JSON
    Java反射得到属性的值和设置属性的值(转)
    java如何得到GET和POST请求URL和参数列表(转)
    Oracle Database 11G R2 标准版 企业版 下载地址(转)
  • 原文地址:https://www.cnblogs.com/Yinku/p/11298017.html
Copyright © 2020-2023  润新知