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;
}

SCUT - 142 - 第n个素数的更多相关文章

  1. Java程序员面试题集(136-150)(转)

    转:http://blog.csdn.net/jackfrued/article/details/17740651 Java程序员面试题集(136-150) 摘要:这一部分主要是数据结构和算法相关的面 ...

  2. Java面试题集(136-150)

    摘要:目,尽管仅仅有15道题目.可是包括的信息量还是非常大的,非常多题目背后的解题思路和算法是非常值得玩味的. 136.给出以下的二叉树先序.中序.后序遍历的序列? 答:先序序列:ABDEGHCF.中 ...

  3. AtCoder Beginner Contest 142【D题】【判断素数的模板+求一个数的因子的模板】

    D - Disjoint Set of Common Divisors Problem Statement Given are positive integers AA and BB. Let us ...

  4. WPF中的常用布局 栈的实现 一个关于素数的神奇性质 C# defualt关键字默认值用法 接口通俗理解 C# Json序列化和反序列化 ASP.NET CORE系列【五】webapi整理以及RESTful风格化

    WPF中的常用布局   一 写在开头1.1 写在开头微软是一家伟大的公司.评价一门技术的好坏得看具体的需求,没有哪门技术是面面俱到地好,应该抛弃对微软和微软的技术的偏见. 1.2 本文内容本文主要内容 ...

  5. Help Hanzo (素数筛+区间枚举)

    Help Hanzo 题意:求a~b间素数个数(1 ≤ a ≤ b < 231, b - a ≤ 100000).     (全题在文末) 题解: a~b枚举必定TLE,普通打表MLE,真是头疼 ...

  6. Java 素数 prime numbers-LeetCode 204

    Description: Count the number of prime numbers less than a non-negative number, n click to show more ...

  7. 求解第N个素数

    任务 求解第 10,0000.100,0000.1000,0000 ... 个素数(要求精确解). 想法 Sieve of Eratosthenes 学习初等数论的时候曾经学过埃拉托斯特尼筛法(Sie ...

  8. 使用BitArray判断素数

    首先显示1024范围内的所有素数,然后显示输入的数是否是素数.1024 是代码中计算的素数的范围,可以修改.计算平方根,是为了确定一个基数的范围.1024的平方根是32,两个超过32 的数相乘,肯定大 ...

  9. 查找素数Eratosthenes筛法的mpi程序

    思路: 只保留奇数 (1)由输入的整数n确定存储奇数(不包括1)的数组大小: n=(n%2==0)?(n/2-1):((n-1)/2);//n为存储奇数的数组大小,不包括基数1 (2)由数组大小n.进 ...

随机推荐

  1. linux运维、架构之路-linux目录结构

    1.linux重要目录 重要目录 说明 /etc 存放系统配置文件.服务启动命令的目录 /root 超级管理员的家目录 /sbin和usr/sbin 超级用户命令的目录 /boot 系统引导程序所在的 ...

  2. Oracle的优化

    Oracle优化:物理优化和逻辑优化.物理优化:1):Oracle的运行环境.2):合理的使用优化器.3):合理配置Oracle实例参数4):建立合适的索引(减少IO)5):将索引数据和表数据分开在不 ...

  3. rk3328设备树学习

    一.用到的rk3328好像使用了设备树 设备树我知道的有三种文件类型,dtbs是通过指令make dtbs编译的二进制文件,供内核使用. 基于同样的软件分层设计的思想,由于一个SoC可能对应多个mac ...

  4. Python pdfkit

    序言 住在地下室的人,依然有仰望星空的权利. pdfkit python使用pdfkit中,如果使用pdfkit.fromurl 或者pdfkit.fromstring等,就会出现上述错误.而且如果你 ...

  5. asp.net mvc大文件上传、断点续传功能。

    文件夹数据库处理逻辑 publicclass DbFolder { JSONObject root; public DbFolder() { this.root = new JSONObject(); ...

  6. 设计模式之动态代理(Java的JDK动态代理实现)

    先来看一下思维导图: 对于JDK的动态代理,孔浩老师说学习的方法是把它记下来. 先写一个主题接口类,表示要完成的一个主题. package com.liwei.dynaproxy; /** * 要代理 ...

  7. 转 opencv红绿灯检测

    整个项目源码:GitHub 引言 前面我们讲完交通标志的识别,现在我们开始尝试来实现交通信号灯的识别 接下来我们将按照自己的思路来实现并完善整个Project. 在这个项目中,我们使用HSV色彩空间来 ...

  8. 修改mac默认python版本 为python3

    mac一般自带python2.7 可以修改 ~/.bash_profile (具体的path取决于你的python3安装路径): vi ~/.bash_profile # 添加这一行 alias py ...

  9. centos 6.9 mysql 安装配置

    1.全新系统,安装mysql yum -y install mysql mysql-server mysql-devel 2.启动mysql service mysqld start 3.修改密码 登 ...

  10. error: exportArchive: You don’t have permission to save the file “HelloWorld.ipa” in the folder “HelloWorld”.

    成功clean环境和生成archive文件之后,最后一步导出ipa包,遇到了权限问题: you don’t have permission to save the file “HelloWorld.i ...