当前位置: 首页 > news >正文

SCUT - 142 - 第n个素数

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\n", 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;  
} 

转载于:https://www.cnblogs.com/Yinku/p/11298017.html

相关文章:

  • 敏捷开发般若敏捷系列之二:什么是敏捷(上)(无住,不住于法,破法执)...
  • C#打包应用程序
  • SCUT - 37 - 手速帝CZK - 分块
  • HDU 1166 敌兵布阵
  • babel
  • 转载 对于struct file_operations中ioctl消失的学习笔记
  • SCUT - 77 - 哈利波特与他的魔法杖
  • 圆满完成 中大 《性能测试与LoadRunner应用》 实战训练课!
  • 利用vi编辑器创建和编辑正文文件
  • c# WinForm开发 DataGridView控件的各种操作总结(单元格操作,属性设置)
  • Simulation of AVL Trees (DYNAMIC)
  • hive中function函数查询
  • 更改Windwos server 2003 域用户密码策略默认配置
  • SCUT - 38 - 屠场的秘密 - 分解
  • 0 or 1 ?
  • 03Go 类型总结
  • canvas实际项目操作,包含:线条,圆形,扇形,图片绘制,图片圆角遮罩,矩形,弧形文字...
  • IDEA 插件开发入门教程
  • ng6--错误信息小结(持续更新)
  • orm2 中文文档 3.1 模型属性
  • Windows Containers 大冒险: 容器网络
  • Yii源码解读-服务定位器(Service Locator)
  • 缓存与缓冲
  • 基于Mobx的多页面小程序的全局共享状态管理实践
  • 来,膜拜下android roadmap,强大的执行力
  • 如何实现 font-size 的响应式
  • 如何优雅的使用vue+Dcloud(Hbuild)开发混合app
  • 学习ES6 变量的解构赋值
  • HanLP分词命名实体提取详解
  • 测评:对于写作的人来说,Markdown是你最好的朋友 ...
  • #我与Java虚拟机的故事#连载12:一本书带我深入Java领域
  • (51单片机)第五章-A/D和D/A工作原理-A/D
  • (Matalb时序预测)WOA-BP鲸鱼算法优化BP神经网络的多维时序回归预测
  • (带教程)商业版SEO关键词按天计费系统:关键词排名优化、代理服务、手机自适应及搭建教程
  • (官网安装) 基于CentOS 7安装MangoDB和MangoDB Shell
  • (六) ES6 新特性 —— 迭代器(iterator)
  • (十)DDRC架构组成、效率Efficiency及功能实现
  • (一)spring cloud微服务分布式云架构 - Spring Cloud简介
  • (转)shell调试方法
  • .bat文件调用java类的main方法
  • .NET Core 将实体类转换为 SQL(ORM 映射)
  • .net 前台table如何加一列下拉框_如何用Word编辑参考文献
  • .NET 设计模式—适配器模式(Adapter Pattern)
  • .NET框架设计—常被忽视的C#设计技巧
  • .NET面试题解析(11)-SQL语言基础及数据库基本原理
  • .NET是什么
  • @property python知乎_Python3基础之:property
  • @property括号内属性讲解
  • @开发者,一文搞懂什么是 C# 计时器!
  • [ vulhub漏洞复现篇 ] GhostScript 沙箱绕过(任意命令执行)漏洞CVE-2019-6116
  • [2013][note]通过石墨烯调谐用于开关、传感的动态可重构Fano超——
  • [2016.7 test.5] T1
  • [Android]常见的数据传递方式
  • [Angular] 笔记 16:模板驱动表单 - 选择框与选项
  • [AS3]URLLoader+URLRequest+JPGEncoder实现BitmapData图片数据保存