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 ...
随机推荐
- 基于STM32F103的Max30100心率、血氧检测代码(转载)
MAX30100是能够读取心率.血氧的传感器,通信方式是通过IIC进行通信.其工作原理是通过红外led灯照射,能够得到心率的ADC值. MAX30100的寄存器可以分为五类,状态寄存器.F ...
- Qt——绘图
1.涉及类 QPainter QPaintEngine QPaintDevice 作为绘图的使用者,只需要关注 QPainter 和 QPaintDevice 2.QPainter 使用 QPain ...
- cf776D Mahmoud and a Dictionary
Mahmoud wants to write a new dictionary that contains n words and relations between them. There are ...
- LeetCode:11. ContainerWithWater(Medium)
原题链接:https://leetcode.com/problems/container-with-most-water/description/ 题目要求:给定n个非负整数a1,a2,...,an ...
- spring+springmvc+maven+mongodb
1.前言 最近项目开发使用到了spring+springmvc+maven+mongodb,项目中的框架是用springboot进项开发的,对于我们中级开发人员来说,有利有弊,好处呢是springbo ...
- 封装一个List集合和datatable相互转换的工具类(可对指定列进行重命名并且指定输出列)
/// <summary> /// List转换为DataTable对象 /// </summary> public class ListTranTableModel { // ...
- c#根据ip获取城市地址
用的API是百度.新浪.淘宝: 1.首先是一个检测获取的值是不是中文的方法,因为有的ip只能识别出来某省,而城市名称则为空返回的json里会出现null或undefined. public stati ...
- iOS-Debug Symbol(调试符号)
Debug Symbol(调试符号) 编译警告 从svn下载下来的文件,到处都是编译警告,看着不爽,找下原因,没想到还是一条大鱼 warning: (i386) /UsersLibrary/Devel ...
- deepin linux 安装/启动jeakins报错:处理
ERROR: No Java executable found in current PATH: /bin:/usr/bin:/sbin:/usr/sbin 安装报错: 1.如还未安装java,则安装 ...
- ubuntu中 VI 方向键、删除键问题
这两天重新装的ubuntu系统,发觉使用VI时,方向键按下去后变成ABCD,删除键无效.网上搜寻一番,应该是VI软件本身的问题,顾卸载重装即可,步骤如下: 1.执行命令 sudo apt-get re ...