博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
素数打表
阅读量:4963 次
发布时间:2019-06-12

本文共 4171 字,大约阅读时间需要 13 分钟。

O(n)
#include    
#include
#include
#include
#include
__int64 *primarr, *v; __int64 q = 1, p = 1; //π(n) __int64 pi(__int64 n, __int64 primarr[], __int64 len) { __int64 i = 0, mark = 0; for (i = len - 1; i > 0; i--) { if (primarr[i] < n) { mark = 1; break; } } if (mark) return i + 1; return 0; } //Φ(x,a) __int64 phi(__int64 x, __int64 a, __int64 m) { if (a == m) return (x / q) * p + v[x % q]; if (x < primarr[a - 1]) return 1; return phi(x, a - 1, m) - phi(x / primarr[a - 1], a - 1, m); } __int64 prime(__int64 n) { char *mark; __int64 mark_len; __int64 count = 0; __int64 i, j, m = 7; __int64 sum = 0, s = 0; __int64 len, len2, len3; mark_len = (n < 10000) ? 10002 : ((__int64)exp(2.0 / 3 * log(n)) + 1); //筛选n^(2/3)或n内的素数 mark = (char *)malloc(sizeof(char) * mark_len); memset(mark, 0, sizeof(char) * mark_len); for (i = 2; i < (__int64)sqrt(mark_len); i++) { if (mark[i]) continue; for (j = i + i; j < mark_len; j += i) mark[j] = 1; } mark[0] = mark[1] = 1; //统计素数数目 for (i = 0; i < mark_len; i++) if (!mark[i]) count++; //保存素数 primarr = (__int64 *)malloc(sizeof(__int64) * count); j = 0; for (i = 0; i < mark_len; i++) if (!mark[i]) primarr[j++] = i; if (n < 10000) return pi(n, primarr, count); //n^(1/3)内的素数数目 len = pi((__int64)exp(1.0 / 3 * log(n)), primarr, count); //n^(1/2)内的素数数目 len2 = pi((__int64)sqrt(n), primarr, count); //n^(2/3)内的素数数目 len3 = pi(mark_len - 1, primarr, count); //乘积个数 j = mark_len - 2; for (i = (__int64)exp(1.0 / 3 * log(n)); i <= (__int64)sqrt(n); i++) { if (!mark[i]) { while (i * j > n) { if (!mark[j]) s++; j--; } sum += s; } } free(mark); sum = (len2 - len) * len3 - sum; sum += (len * (len - 1) - len2 * (len2 - 1)) / 2; //欧拉函数 if (m > len) m = len; for (i = 0; i < m; i++) { q *= primarr[i]; p *= primarr[i] - 1; } v = (__int64 *)malloc(sizeof(__int64) * q); for (i = 0; i < q; i++) v[i] = i; for (i = 0; i < m; i++) for (j = q - 1; j >= 0; j--) v[j] -= v[j / primarr[i]]; sum = phi(n, len, m) - sum + len - 1; free(primarr); free(v); return sum; } int main() { __int64 n; __int64 count; int h; clock_t start, end; while(scanf("%I64d", &n)!=EOF) { p=1; q=1; start = clock(); count = prime(n); end = clock() - start; printf("%I64d(%d亿)内的素数个数为%I64d\n",n,n/100000000,count); printf("用时%lf毫秒\n",(double)end/1000); } return 0; }
Meissel-Lehmer
/*遇到素数需要打表时,先估算素数的个数:num = n / lnx;num为大概数字,越大误差越小(只是估计,用于估算素数表数组大小)这个打表法效率貌似很高,网上说几乎达到了线性时间(不知道是真是假=。=)*/#include
#include
#include
#include
#include
using namespace std;int n;bool visit[10100000];int prime[10000000];void init_prim(){ memset(visit, true, sizeof(visit)); int num = 0; for (int i = 2; i <= n; ++i) { if (visit[i] == true) { num++; prime[num] = i; } for (int j = 1; ((j <= num) && (i * prime[j] <= n)); ++j) { visit[i * prime[j]] = false; if (i % prime[j] == 0) break; //点睛之笔 } }}int main(){ memset(prime, 0, sizeof(prime)); int count = 0; cin>>n; init_prim(); for(int i = 0; i <= n; ++i) if(prime[i]) { cout<
<<" "; count++; } cout<
usual

 

转载于:https://www.cnblogs.com/Aragaki/p/7277091.html

你可能感兴趣的文章
大话重构连载5:软件改动的四种动机
查看>>
配置完PA13|PA14|PA15|PB3|PB4后,板子不能下载程序了
查看>>
推荐系统实战(二) —— FM
查看>>
LIGHTOJ 1104 Birthday Paradox 概率题 好玩的题
查看>>
mongoDB查询数据
查看>>
DMZ主机
查看>>
leveldb 源码阅读,细节记录memberTable
查看>>
如何从电脑直接控制安卓手机 监控安卓手机 安卓手机如何控制安卓手机
查看>>
百科知识 天气图标示例
查看>>
C#.NET常见问题(FAQ)-方法参数带ref是什么意思
查看>>
javascript判断数据类型
查看>>
SpringMVC GET请求中文数据传递到Server端乱码
查看>>
eclipse 关闭web项目无用校验
查看>>
js 根据身份证获取出生日期及性别
查看>>
PHPstorm+XDebug+Chrome/Firefox超详细教程(图文)
查看>>
织梦常用标签汇总-------未完待续
查看>>
VMWare ESX/ESXi 虚拟机硬盘的厚置备(Thick Provision)与精简置备(Thin Provision)的转换
查看>>
(译文)Python中的staticmethod与classmethod
查看>>
表单验证
查看>>
总结-SQL注入
查看>>