SCUT - 142 - 第n个素数
但是洲阁筛打表还是超时了,打的表不够长吧,在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个素数的更多相关文章
- Java程序员面试题集(136-150)(转)
转:http://blog.csdn.net/jackfrued/article/details/17740651 Java程序员面试题集(136-150) 摘要:这一部分主要是数据结构和算法相关的面 ...
- Java面试题集(136-150)
摘要:目,尽管仅仅有15道题目.可是包括的信息量还是非常大的,非常多题目背后的解题思路和算法是非常值得玩味的. 136.给出以下的二叉树先序.中序.后序遍历的序列? 答:先序序列:ABDEGHCF.中 ...
- AtCoder Beginner Contest 142【D题】【判断素数的模板+求一个数的因子的模板】
D - Disjoint Set of Common Divisors Problem Statement Given are positive integers AA and BB. Let us ...
- WPF中的常用布局 栈的实现 一个关于素数的神奇性质 C# defualt关键字默认值用法 接口通俗理解 C# Json序列化和反序列化 ASP.NET CORE系列【五】webapi整理以及RESTful风格化
WPF中的常用布局 一 写在开头1.1 写在开头微软是一家伟大的公司.评价一门技术的好坏得看具体的需求,没有哪门技术是面面俱到地好,应该抛弃对微软和微软的技术的偏见. 1.2 本文内容本文主要内容 ...
- Help Hanzo (素数筛+区间枚举)
Help Hanzo 题意:求a~b间素数个数(1 ≤ a ≤ b < 231, b - a ≤ 100000). (全题在文末) 题解: a~b枚举必定TLE,普通打表MLE,真是头疼 ...
- Java 素数 prime numbers-LeetCode 204
Description: Count the number of prime numbers less than a non-negative number, n click to show more ...
- 求解第N个素数
任务 求解第 10,0000.100,0000.1000,0000 ... 个素数(要求精确解). 想法 Sieve of Eratosthenes 学习初等数论的时候曾经学过埃拉托斯特尼筛法(Sie ...
- 使用BitArray判断素数
首先显示1024范围内的所有素数,然后显示输入的数是否是素数.1024 是代码中计算的素数的范围,可以修改.计算平方根,是为了确定一个基数的范围.1024的平方根是32,两个超过32 的数相乘,肯定大 ...
- 查找素数Eratosthenes筛法的mpi程序
思路: 只保留奇数 (1)由输入的整数n确定存储奇数(不包括1)的数组大小: n=(n%2==0)?(n/2-1):((n-1)/2);//n为存储奇数的数组大小,不包括基数1 (2)由数组大小n.进 ...
随机推荐
- 【Luogu4221】[WC2018] 州区划分
题目链接 题目描述 略 Sol 一个州合法就是州内点形成的子图中 不存在欧拉回路(一个点也算欧拉回路). 这个东西显然就状压 dp 一下: 设 \(f[S]\) 表示当前考虑了 \(S\) 这个集合内 ...
- 【NOIP2013模拟】DY引擎
题目 BOSS送给小唐一辆车.小唐开着这辆车从PKU出发去ZJU上课了. 众所周知,天朝公路的收费站超多的.经过观察地图,小唐发现从PKU出发到ZJU的所有路径只会有N(2<=N<=300 ...
- javaScript中的 call 和 apply
call 和apply都可以实现函数的调用 // 普通函数的调用 function foo() { console.log('foo'); } foo(); // foo foo.call(); // ...
- awk基础学习
2019-12-20 需要巧记,很多格式,学习难度:grep.sed.awk awk知识概述 1三剑客awk命令介绍2三剑客awk命令执行原理语法结构3三剑客awk命令实操练习查询替换信息排除(取反) ...
- SpringBoot搭建基于Spring+SpringMvc+Mybatis的REST服务
Maven Plugin管理 通常,让你的Maven POM文件继承 spring-boot-starter-parent,并声明一个或多个 Starter POMs依赖即可. spring-boot ...
- 实用工具/API
实用工具/API PNG图片无损压缩 在线给图片加水印 随机密码生成 随机头像生成 微博一键清理工具 CSS压缩 在线工具 免费虚拟主机 技术摘要 https://github.com/biezhi/ ...
- D - Cheerleaders(第三周)
D - Cheerleaders 题目链接:https://vjudge.net/contest/154063#problem/D 题目大意: 给你一个 n∗m 的方格,现在有 k 个相同石子,我们要 ...
- 利用python进行数据分析--pandas入门2
随书练习,第五章 pandas入门2 # coding: utf-8 # In[1]: from pandas import Series,DataFrame import pandas as pd ...
- postgresql批量删除表
CREATE FUNCTION del_ora_table() RETURNS void AS $$ DECLARE tmp ); DECLARE names CURSOR FOR select ta ...
- windows 2008 gpt
新服务器,4T硬盘,U盘安装Windows Server 2008 R2. 把2008的镜像用UltraISO写入U盘. 安装到分区那块,主分区200G,剩余分区系统自动给分为: 2T + 剩余 两块 ...