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. hive group by distinct区别以及性能比较

    Hive去重统计 相信使用Hive的人平时会经常用到去重统计之类的吧,但是好像平时很少关注这个去重的性能问题,但是当一个表的数据量非常大的时候,会发现一个简单的count(distinct order ...

  2. MySQL 5.7

    博客地址:https://www.cnblogs.com/runningStudy/p/6444047.html mysql官网下载地址:https://downloads.mysql.com/arc ...

  3. 微信小程序-wxml-空格

    必须要在<text>标签中 先在标签中写decode="{{true}}"然后 就代表空格了   占一个中文字符

  4. Codecombat 游戏攻略(计算机科学三)

    第二关 赋值运算符-=字符串拼串循环语句while // 你可以把字符串连起来,或者把数字连接到字符串. // 一起唱歌,使用字符串连接: // X potions of health on the ...

  5. WEB Fuzz中需要关注的7种响应

    WEB应用模糊测试(WEB Fuzz)是一种特殊形式的网络协议模糊测试,专门关注遵循HTTP规范的网络数据包. WEB Fuzz并不是新的概念,目前有多种WEB应用模糊测试器(WEB Fuzzer), ...

  6. PHP代码修改后提交,无法立即生效

    今天遇到一个坑爹的问题,就是我修改了PHP代码,提交到网站根目录以后,刷新浏览器居然无法立即生效,差不多得一分钟的样子再去刷新,才会看到更改后的效果. 出现这个问题的原因,是因为手头的项目需要较高的P ...

  7. SQL Server系列之 删除大量数据

    一.写在前面 - 想说爱你不容易 为了升级数据库至SQL Server 2008 R2,拿了一台现有的PC做测试,数据库从正式库Restore(3个数据库大小夸张地达到100G+),而机器内存只有可怜 ...

  8. php system exexc 立即返回

    有时候会用到php调用服务器端的其它可执行文件,system和exec函数都是阻塞执行的,执行完第三方程序再返回. 如果我们需要立即返回,让第三方程序在后台继续执行,调用方式如下: linux,noh ...

  9. Android传感器系统架构【转】

    本文转载自:http://blog.csdn.net/qianjin0703/article/details/5942579 版权声明:本文为博主原创文章,未经博主允许不得转载. 1. 体系结构 2. ...

  10. 图像bayer格式介绍【转】

    本文转载自:http://www.cnblogs.com/whw19818/p/6223143.html 1 图像bayer格式介绍 bayer格式图片是伊士曼·柯达公司科学家Bryce Bayer发 ...