找回密码
 欢迎注册
楼主: medie2005

[讨论] 阶乘和素数个数

[复制链接]
发表于 2008-11-17 19:22:53 | 显示全部楼层
关键是计算到那个程度 需要多少时间? 我想算10^16的就很长 否则不会在70年代算不出
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-11-17 20:30:12 | 显示全部楼层
原帖由 无心人 于 2008-11-17 15:28 发表 你还是想办法把 $O(n^{2/3})$ 的$pi(n)$算法 先做好了吧
这篇论文我曾上传到论坛的;在 Donald E.Knuth 著的 TAOCP 中某道习题中提及。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2008-11-17 20:53:28 | 显示全部楼层
呵呵,gxq说的那篇文章很好找,google一下就能找到免费的原文。 我找了一下,发现还有时间复杂度为$O(n^(3/5))$的算法来计算$pi(n)$, 不过,好像是没什么人用那个算法来计算$pi(n)$,看样子只是时间复杂度好看点而已。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2008-11-17 21:03:51 | 显示全部楼层
另外,有一个网站:PrimeDatabase。里面可以查到第1到第$10^12$个素数。 我对网页不熟悉,是不是能写一个脚本,每隔一段时间就查一个数,然后记录返回的素数?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2008-11-19 12:40:53 | 显示全部楼层
关于计算$pi(n)$,目前有时间复杂度为$O(n^((1/2)+varepsilon))$,空间复杂度为$O(n^((1/4)+varepsilon))$的算法。 至于$O(n^((2/3)+varepsilon))$的算法,我找到了intfree(张一飞,mathe应该还记得^_^)写的一个dephi版本的C++版,在我机器上,计算$pi(4*10^9)$需要0.5秒。 代码如下:
  1. #include <iostream.h>
  2. #include <math.h>
  3. #include <windows.h>
  4. const unsigned default_n=4000000000;
  5. const int maxlen=1000;
  6. int primes[maxlen];
  7. int len;
  8. int sum;
  9. unsigned int n;
  10. int m=7;
  11. int Q=1;
  12. int phiQ=1;
  13. int* v;
  14. bool string2int(unsigned int& n,char* s);
  15. void init(void);
  16. unsigned int phi(unsigned int x,int a);
  17. void main(void){
  18. char number_string[80];
  19. unsigned int time;
  20. cout<<"calc pi(n)\n";
  21. cout<<"n(default = "<<default_n<<") = ";
  22. cin.get(number_string,80);
  23. if(!string2int(n,number_string))n=default_n;
  24. time=GetTickCount();
  25. init();
  26. int num=(int)phi(n,len)-sum+len-1;
  27. time=GetTickCount()-time;
  28. GlobalFree(v);
  29. cout<<"pi(n)="<<num<<"("<<time<<"ms)\n";
  30. cout<<"press any key to continue...";
  31. cin.get();
  32. cin.get();
  33. }
  34. void init(void){
  35. int max;
  36. int sqrt_max;
  37. bool* mark;
  38. int i,j;
  39. int len2,len3;
  40. int s;
  41. max=(int)pow(1.0*n,2.0/3.0);
  42. sqrt_max=(int)sqrt(max);
  43. mark=(bool*)GlobalAlloc(GMEM_FIXED|GMEM_ZEROINIT,max);
  44. for(i=2;i<sqrt_max;++i){
  45. if(!mark[i]){
  46. j=i*i;
  47. while(j<max){
  48. mark[j]=true;
  49. j+=i;
  50. }
  51. }
  52. }
  53. for(len=0,i=2;(unsigned)i*i*i<=n;++i){
  54. if(!mark[i])primes[++len]=i;
  55. }
  56. for(j=max-1,sum=0,s=0,len2=len;(unsigned)i*i<=n;++i){
  57. if(!mark[i]){
  58. ++len2;
  59. while((unsigned)i*j>n){
  60. if(!mark[j])++s;
  61. --j;
  62. }
  63. sum+=s;
  64. }
  65. }
  66. for(len3=len2;i<max;++i){
  67. if(!mark[i])++len3;
  68. }
  69. sum=(len2-len)*len3-sum;
  70. sum+=len*(len-1)/2-len2*(len2-1)/2;
  71. if(m>len)m=len;
  72. for(i=1;i<=m;++i){
  73. Q*=primes[i];
  74. phiQ*=primes[i]-1;
  75. }
  76. v=(int*)GlobalAlloc(GMEM_FIXED,Q*sizeof(int));
  77. for(i=0;i<Q;++i)v[i]=i;
  78. for(i=1;i<=m;++i){
  79. for(j=Q-1;j>=0;--j){
  80. v[j]-=v[j/primes[i]];
  81. }
  82. }
  83. GlobalFree(mark);
  84. }
  85. bool string2int(unsigned int& n,char* s){
  86. unsigned int val=0;
  87. for(int i=0;s[i];++i){
  88. if(s[i]>'9'||s[i]<'0')return false;
  89. val*=10;
  90. val+=s[i]-'0';
  91. if(val>default_n)return false;
  92. }
  93. n=val;
  94. return true;
  95. }
  96. unsigned int phi(unsigned int x,int a){
  97. if(a==m){
  98. return (x/Q)*phiQ+v[x%Q];
  99. }
  100. if(x<(unsigned)primes[a]){
  101. return 1;
  102. }
  103. return phi(x,a-1)-phi(x/primes[a],a-1);
  104. }
复制代码
另外,哪位能写个可以自动到PrimeDatabase上查询,并能记录结果的脚本?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-11-19 13:34:59 | 显示全部楼层
原帖由 medie2005 于 2008-11-19 12:40 发表 关于计算$pi(n)$,目前有时间复杂度为$O(n^((1/2)+varepsilon))$,空间复杂度为$O(n^((1/4)+varepsilon))$的算法。 ...
可否提供参考资料?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-11-19 14:35:41 | 显示全部楼层
回15楼, 张一飞我知道,张一飞是3届(2000,2001,2002)IOI国家集训队的成员,第14届国际信息学奥林匹克竞赛金牌获得者。intfree的这个代码我也看过(可惜我我看不懂), 但我不知道intfree就是张一飞。楼主怎么知道的?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-11-19 14:44:54 | 显示全部楼层
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-11-19 15:32:17 | 显示全部楼层
这个不难,在Linux下面直接用脚本调用wget就可以了。然后将返回的结果找关键字就可以了。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-11-19 15:37:20 | 显示全部楼层
如果上面intfree的代码是$O(n^{2/3})$,既然计算到$4*10^9$只需要0.5秒,那么计算到$4*10^12$也就需要100倍,50秒左右,还是可以容忍的
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-11-23 16:03 , Processed in 0.025203 second(s), 15 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表