/// A heavily optimized sieve
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
typedef unsigned int u32;
typedef unsigned long long ull;
const char pr60[]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59};
const char masks[][4]={
{3,7,11,13},
{3,17,19,23},
{2,29,31},
{2,37,41},
{2,43,47},
{2,53,59}
};
const u32 segsize=65536;
void Apply_mask(u32*a,u32*b,u32 l1,u32 l2){
u32 t=0;
for(u32 q=0,r=l1/l2;q<r;++q)
for(u32 i=0;i<l2;++i)
a[t++]|=b[i];
for(u32 i=0;t<l1;++i)
a[t++]|=b[i];
}
void Gen_mask_sub(u32*a,u32 l1,u32 b){
u32 st=b>>1,rt=0;
while(rt<l1){
a[rt]|=1<<st;
st+=b;
if(st>=30)st-=30,++rt;
if(st>=30)st-=30,++rt;
}
}
void PrintMask(u32*a,u32 len){
printf("Mask of len %u\n",len*60);
for(u32 i=0;i<len;++i){
for(u32 j=0;j<30;++j)
if((a[i]&(1<<j)))
printf("%llu\n",i*60ull+j*2ull+1ull);
}
}
u32 Gen_mask(u32*a,int id){
int len=masks[id][0];
u32 ll=1;
for(int i=1;i<=len;++i)
ll*=masks[id][i];
memset(a,0,4*ll);
for(int i=1;i<=len;++i)
Gen_mask_sub(a,ll,masks[id][i]);
// PrintMask(a,ll);
return ll;
}
const u32 mask=0x1a4b3496;
const u32 pr60_m=0xdb4b3491;
u32 pr[10000][4],prl;
int main(){
ull ma,tma,tmx;scanf("%llu",&ma);
tma=(ma-1)/60+1;
tmx=tma*60;//upper limit
u32*sieve=new u32[tma];// getting a sieve ready
u32*maske=new u32[7429];
std::fill(sieve,sieve+tma,mask);
for(int i=0;i<6;++i)
Apply_mask(sieve,maske,tma,Gen_mask(maske,i)); ull preseg=std::min(tmx,ull(sqrt(ma)/60)+1);
u32 j=61;
for(;ull(j)*j<=preseg*60;j+=2){
u32 v=j/60,u=(j%60)>>1;
if(!(sieve[v]&(1<<u))){
v=j/30,u=j%30;
u32 rt=j*3/60,st=(j*3%60)>>1;
while(rt<preseg){
sieve[rt]|=1<<st;
rt+=v;
st+=u;
if(st>=30)st-=30,++rt;
}
pr[prl][0]=v;
pr[prl][1]=u;
pr[prl][2]=rt;
pr[prl][3]=st;
prl++;
}
} // Non-segmented sieve core
if(preseg==tmx)goto end;
for(u32 segl=preseg;segl<tma;segl+=segsize){
u32 segr=std::min(segl+segsize,u32(tma));
for(;ull(j)*j<=segr*60;j+=2){
u32 v=j/60,u=(j%60)>>1;
if(!(sieve[v]&(1<<u))){
v=j/30,u=j%30;
ull t=j*ull(j);
u32 rt=t/60,st=t%60>>1;
pr[prl][0]=v;
pr[prl][1]=u;
pr[prl][2]=rt;
pr[prl][3]=st;
prl++;
}
}
for(int i=0;i<prl;++i){
u32 v=pr[i][0],u=pr[i][1],rt=pr[i][2],st=pr[i][3];
while(rt<segr){
sieve[rt]|=1<<st;
rt+=v;
st+=u;
if(st>=30)st-=30,++rt;
}
pr[i][0]=v;
pr[i][1]=u;
pr[i][2]=rt;
pr[i][3]=st;
}
}
end:
sieve[0]=pr60_m;
int count=1;
for(u32 i=0;i<tma;++i){
for(u32 j=0;j<30;++j)
if(!(sieve[i]&(1<<j)))++count;
}
for(ull a=tmx-1;a>ma;a-=2){
u32 i=a/60,j=a%60>>1;
if(!(sieve[i]&(1<<j)))--count;
}
printf("%d\n",count);
return 0;
}

一个Eratosthenes筛。单线程,筛1e9<0.5s,程序运行时间<0.7s。(7700k 4.2GHz)

(注意后面的统计部分效率极其低下,可用查表位运算替代。)

0.只留奇数项

1.压位,30pack int

2.对于<60的素数用很快的筛子一遍

3.分段筛法

Optimize Prime Sieve的更多相关文章

  1. SPOJ #2 Prime Generator

    My first idea was Sieve of Eratosthenes, too. But obviously my coding was not optimal and it exceede ...

  2. ZOJ 1842 Prime Distance(素数筛选法2次使用)

    Prime Distance Time Limit: 2 Seconds      Memory Limit: 65536 KB The branch of mathematics called nu ...

  3. 10 The Go Programming Language Specification go语言规范 重点

    The Go Programming Language Specification go语言规范 Version of May 9, 2018 Introduction 介绍 Notation 符号 ...

  4. 06 Frequently Asked Questions (FAQ) 常见问题解答 (常见问题)

    Frequently Asked Questions (FAQ) Origins 起源 What is the purpose of the project? What is the history ...

  5. go语言之并发

    简介           多核处理器越来越普及,那有没有一种简单的办法,能够让我们写的软件释放多核的威力?答案是:Yes.随着Golang, Erlang, Scale等为并发设计的程序语言的兴起,新 ...

  6. [转载] Go语言并发之美

    原文: http://qing.blog.sina.com.cn/2294942122/88ca09aa33002ele.html 简介           多核处理器越来越普及,那有没有一种简单的办 ...

  7. [转Go-简洁的并发 ]

    http://www.yankay.com/go-clear-concurreny/ Posted on 2012-11-28by yankay 多核处理器越来越普及.有没有一种简单的办法,能够让我们 ...

  8. Go语言规格说明书 之 Go语句(Go statements)

    go version go1.11 windows/amd64 本文为阅读Go语言中文官网的规则说明书(https://golang.google.cn/ref/spec)而做的笔记,介绍Go语言的 ...

  9. (第三场) H Diff-prime Pairs 【数论-素数线性筛法+YY】

    题目链接 题目描述 Eddy has solved lots of problem involving calculating the number of coprime pairs within s ...

随机推荐

  1. 学习RUNOOB.COM进度一

    了解MongoDB 由C++语言编写的,是一个基于分布式文件存储的开源数据库系统.在高负载的情况下,添加更多的节点,可以保证服务器性能. 特点 面向文档,操作简单容易 设置任何索引,实现更快排序 本地 ...

  2. python2.7练习小例子(八)

        8):题目:输出 9*9 乘法口诀表.     程序分析:分行与列考虑,共9行9列,i控制行,j控制列.     程序源代码: #!/usr/bin/python # -*- coding: ...

  3. 12 TCP服务器 进程 线程 非阻塞

    1.单进程服务器 from socket import * serSocket = socket(AF_INET, SOCK_STREAM) # 重复使用绑定的信息 serSocket.setsock ...

  4. php-configure错误解决

    configure: error: libjpeg.(a|so) not foundconfigure: error: libjpeg.(a|so) not foundln -sf libjpeg.s ...

  5. 最后一片蓝海的终极狂欢-写在Win10发布前夕

    作为一名Windows8.x+系统平台从业者,从工作伊始,耳边不断充斥着Windows将走向没落的言论,Win10今日晚些时候即将发布,笔者借此机会,说说自己的看法. 早在2012年的时候,IDC曾预 ...

  6. 命令行下对apk签名

    l创建key,需要用到keytool.exe (位于jdk安装目录\bin目录下),使用产生的key对apk签名用到的是jarsigner.exe (位于jdk安装目录\bin目录下),把上两个软件所 ...

  7. mybatis <collection>标签 类型为string时无法获取重复数据错误

    1.场景: fyq_share_house 表 和 fyq_sh_tag 表 两张表是一对多的关系, 一个楼盘对应多个标签,在实体类ShareHouse中使用 /** * 楼盘标签 */ privat ...

  8. Python 3基础教程24-读取csv文件

    本文来介绍用Python读取csv文件.什么是csv(Comma-Separated Values),也叫逗号分割值,如果你安装了excel,默认会用excel打开csv文件. 1. 我们先制作一个c ...

  9. 牛客网暑期ACM多校训练营(第七场):J-Sudoku Subrectangles

    链接:J-Sudoku Subrectangles 题意:给出 n * m 的字母矩阵,公52种字母.求出不含重复元素的子矩阵的个数. 题解: L[i][j]:s[i][j] ~ s[i][ j - ...

  10. [USACO19JAN]Cow Poetry

    题面 Solution: 这是一道很好的dp题. 一开始看不懂题面没有一点思路,看了好久题解才看懂题目... \(y[i]\) 为第 \(i\) 个词结尾,\(l[i]\) 为第 \(i\) 个词长度 ...