Optimize Prime Sieve
/// 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的更多相关文章
- SPOJ #2 Prime Generator
My first idea was Sieve of Eratosthenes, too. But obviously my coding was not optimal and it exceede ...
- ZOJ 1842 Prime Distance(素数筛选法2次使用)
Prime Distance Time Limit: 2 Seconds Memory Limit: 65536 KB The branch of mathematics called nu ...
- 10 The Go Programming Language Specification go语言规范 重点
The Go Programming Language Specification go语言规范 Version of May 9, 2018 Introduction 介绍 Notation 符号 ...
- 06 Frequently Asked Questions (FAQ) 常见问题解答 (常见问题)
Frequently Asked Questions (FAQ) Origins 起源 What is the purpose of the project? What is the history ...
- go语言之并发
简介 多核处理器越来越普及,那有没有一种简单的办法,能够让我们写的软件释放多核的威力?答案是:Yes.随着Golang, Erlang, Scale等为并发设计的程序语言的兴起,新 ...
- [转载] Go语言并发之美
原文: http://qing.blog.sina.com.cn/2294942122/88ca09aa33002ele.html 简介 多核处理器越来越普及,那有没有一种简单的办 ...
- [转Go-简洁的并发 ]
http://www.yankay.com/go-clear-concurreny/ Posted on 2012-11-28by yankay 多核处理器越来越普及.有没有一种简单的办法,能够让我们 ...
- Go语言规格说明书 之 Go语句(Go statements)
go version go1.11 windows/amd64 本文为阅读Go语言中文官网的规则说明书(https://golang.google.cn/ref/spec)而做的笔记,介绍Go语言的 ...
- (第三场) H Diff-prime Pairs 【数论-素数线性筛法+YY】
题目链接 题目描述 Eddy has solved lots of problem involving calculating the number of coprime pairs within s ...
随机推荐
- DAG上dp思想
DAG上DP的思想 在下最近刷了几道DAG图上dp的题目.要提到的第一道是NOIP原题<最优贸易>.这是一个缩点后带点权的DAG上dp,它同时规定了起点和终点.第二道是洛谷上的NOI导刊题 ...
- Linux篇:因为修改了/etc/sudoers 文件的权限导致的问题
因为想要把sudo变成免密码所以就查了网上的教程.说是要修改/etc/sudoers文件,但是修改的时候发现这个文件是只读, 所以就 /etc/sudoers 结果就导致了接下来用sudo的时候提示如 ...
- SharePoint显示错误信息
在SharePoint项目中,一般如果发生错误,SharePoint会弹出它自定义的报错页面,一般就显示"Something went wrong",如果光是看这一句话, ...
- n个台阶,每次都可以走一步,走两步,走三步,走到顶部一共有多少种可能
分析 第一个台阶 1第二个台阶 11 2 //走两次1步或者走1次两步第三个台阶 111 12 21 3 第四个台阶 1111 112 121 211 22 13 31 思想:4阶台阶, ...
- 去掉google play专为手机设计标识
google play上的应用默认都会有个“专为手机设计”的标识 有时应用明明已经针对平板作了优化,但为什么这个标识还在呢,如何去掉这个标识呢,其实只需要两个步骤就好了: 1. 标记为支持高分辨率 & ...
- Promise关键知识
异步是ES6中使用频率最高的特性之一,也是面试中经常会被问到的问题,特此整理了相应的笔记 一.Promise的三种状态 pending-异步操作没有结束 fulfilled-异步操作已成功结束,最常见 ...
- [P2387魔法森林
题面 题意: 给出一个图,边权有两维,a与b. 求1到n的一条路径使得路径经过的边的最大的a与b的和最小,输出最小之和. \(Solution:\) 如果做过这题,那么就显得很简单了很好想了. 又是想 ...
- Python 并发编程:PoolExecutor 篇
个人笔记,如有疏漏,还请指正. 使用多线程(threading)和多进程(multiprocessing)完成常规的并发需求,在启动的时候 start.join 等步骤不能省,复杂的需要还要用 1-2 ...
- vim使用注意事项
vim使用注意事项 1. 中文编码的问题 中文编码有很多,如果文件与vim的终端界面使用的编码不同,那么在vim显示的文件内容将会是一堆乱码. 2. 语系编码转换 命令iconv可以将语系编码进行转换 ...
- 软件工程项目组Z.XML会议记录 2013/11/20
软件工程项目组Z.XML会议记录 [例会时间]2013年11月20日星期三21:00-22:00 [例会形式]小组讨论 [例会地点]学生公寓3号楼会客厅 [例会主持]李孟 [会议记录]李孟 会议整体流 ...