[51nod 1184]第N个质数

题目大意

找第n个质数,n<=1e9

乱搞

Drin_E大爷教我的洲阁筛。
但是好像不是正统。
我们可以二分,所以只是判断质数个数的问题。
设c[i]表示第i个质数。
f[i]表示i以内质数个数。
设g(n,m)表示n以内不被c[1~m]整除的数个数。
设q=√n,那么n以内质数个数为f[q]+g(n,f[q])-1(1不是质数要减去)
显然g(n,m)=g(n,m-1)-g(n/c[m],m-1)
注意判边界m=0或1
还有玄学优化
设maxn为预处理范围
当n<=maxn时
如果f[n]<=m,只有1符合返回1
否则若f[√n]<=m,返回f[n]+1-m(除了m个质数外的质数都行)
具体见代码。
复杂度不会证。
maxn开到1e7差不多。

#include<cstdio>
#include<algorithm>
#include<cmath>
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
typedef long long ll;
const int maxn=12500000+10;
ll f[maxn],c[maxn];
bool bz[maxn];
ll i,j,k,t,n,m,q,top;
ll l,r,mid;
ll g(ll n,int m){
    if (!m) return n;
    if (m==1) return n-n/2;
    if (n<=maxn-10){
        if (f[n]<=m) return 1;
        if (f[(int)sqrt(n)]<=m) return f[n]+1-m;
    }
    return g(n,m-1)-g(n/c[m],m-1);
}
ll count(ll n){
    q=floor(sqrt(n));
    return f[q]+g(n,f[q])-1;
}
int main(){
    fo(i,2,maxn-10){
        if (!bz[i]) c[++top]=i;
        fo(j,1,top){
            if (i*c[j]>maxn-10) break;
            bz[i*c[j]]=1;
            if (i%c[j]==0) break;
        }
    }
    f[1]=0;
    fo(i,2,maxn-10) f[i]=f[i-1]+(!bz[i]);
    scanf("%d",&n);
    l=1;r=22801763489;
    while (l<r){
        mid=(l+r)/2;
        if (count(mid)>=n) r=mid;else l=mid+1;
    }
    printf("%lld\n",l);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值