麦森数
题目描述
形如2P-1的素数称为麦森数,这时P一定也是个素数。但反过来不一定,即如果P是个素数,2P-1不一定也是素数。到1998年底,人们已找到了37个麦森数。最大的一个是P=3021377,它有909526位。麦森数有许多重要应用,它与完全数密切相关。
任务:从文件中输入P(1000<P<3100000),计算2P-1的位数和最后500位数字(用十进制高精度数表示)
输入输出格式
输入格式:
文件中只包含一个整数P(1000<P<3100000)
输出格式:
第一行:十进制高精度数2^P-1的位数。
第2-11行:十进制高精度数2^P-1的最后500位数字。(每行输出50位,共输出10行,不足500位时高位补0)
不必验证2^P-1与P是否为素数。
输入输出样例
1279
386 00000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000 00000000000000104079321946643990819252403273640855 38615262247266704805319112350403608059673360298012 23944173232418484242161395428100779138356624832346 49081399066056773207629241295093892203457731833496 61583550472959420547689811211693677147548478866962 50138443826029173234888531116082853841658502825560 46662248318909188018470682222031405210266984354887 32958028878050869736186900714720710555703168729087
1 #include<cmath> 2 #include<cstdio> 3 #define mod 100000 4 int p,s=1650; 5 long long a[110],b[110],c[300],d; 6 void write(long long x,int k){ 7 if(!k) return; 8 write(x/10,k-1); 9 putchar(x%10+'0'); 10 } 11 void rid1(){ 12 for(int i=0;i<=99;i++){ 13 a[i]=a[i]*2+d,d=0; 14 if(a[i]>=mod){ 15 d+=a[i]/mod; 16 a[i]%=mod; 17 } 18 } 19 d=0; 20 } 21 int rid2(){ 22 for(int i=0;i<=99;i++) 23 for(int j=0;j<=99;j++) 24 c[i+j]+=a[i]*b[j]; 25 for(int i=0;i<=99;i++) a[i]=c[i]%mod,c[i+1]+=c[i]/mod,c[i]=0; 26 } 27 int main(){ 28 scanf("%d",&p); 29 printf("%d\n",(int)(log10(2)*p+1)); 30 a[0]++; 31 if(p>s){ 32 for(int i=1;i<=s;i++) rid1(); 33 for(int i=0;i<=99;i++) b[i]=a[i]; 34 p-=s; 35 while(p>s) rid2(),p-=s; 36 } 37 for(int i=1;i<=p;i++) rid1(); 38 a[0]--; 39 for(int i=99,j=1;i>=0;i--,j++){ 40 write(a[i],5); 41 if(j%10==0) putchar('\n'); 42 } 43 return 0; 44 }
不打快速幂是门美德,然而。。。
形如2P-1的素数称为麦森数, 这时P一定也是个素数. 但反过来不一定, 即如果P是个素数, 2P-1不一定也是素数. 在1998年底, 人们找到了37个麦森数. 当时最大的一个是P=3021377, 它有909526位. 但是截止到2013年2月, 美国中央密苏里大学数学家库珀领导的研究小组通过参加一个名为“互联网梅森素数大搜索”(GIMPS)项目, 日前发现了第48个梅森素数——P=57885161; 该素数也是目前已知的最大素数, 有17425170位. 如果用普通字号将它连续打印下来, 它的长度可超过65公里! 美国数学学会发言人布林说:“超大素数令数学家和计算机科学家感到兴奋.” 他认为这是素数探究的一项重大突破. 麦森数有许多重要应用, 它与完全数密切相关. 所以, 给出一个P, 请计算出2P-1.
一个整数P.
第一行: 十进制高精度数2P-1的位数.
第2-21行: 十进制高精度数2P-1的最后1000位数字. (每行输出1000位, 共输出20行, 不足1000位时高位补0)
1279
386 00000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000 00000000000000104079321946643990819252403273640855 38615262247266704805319112350403608059673360298012 23944173232418484242161395428100779138356624832346 49081399066056773207629241295093892203457731833496 61583550472959420547689811211693677147548478866962 50138443826029173234888531116082853841658502825560 46662248318909188018470682222031405210266984354887 32958028878050869736186900714720710555703168729087
1000≤P<2147483647
我。。。我服。
思路:某种数学公式+高精+快速幂
代码实现:
1 #include<cmath> 2 #include<cstdio> 3 #define mod 100000 4 int p,s=1650; 5 long long a[300],b[300],c[300],d; 6 void write(long long x,int k){ 7 if(!k) return; 8 write(x/10,k-1); 9 putchar(x%10+'0'); 10 } 11 void rid1(){ 12 for(int i=0;i<=199;i++) 13 for(int j=0;i+j<=199;j++){ 14 c[i+j]+=a[i]*b[j]; 15 if(c[i+j]>=mod){ 16 c[i+j+1]+=c[i+j]/mod; 17 c[i+j]%=mod; 18 } 19 } 20 for(int i=0;i<=199;i++) a[i]=c[i],c[i]=0; 21 } 22 void rid2(){ 23 for(int i=0;i<=199;i++) 24 for(int j=0;i+j<=199;j++){ 25 c[i+j]+=b[i]*b[j]; 26 if(c[i+j]>=mod){ 27 c[i+j+1]+=c[i+j]/mod; 28 c[i+j]%=mod; 29 } 30 } 31 for(int i=0;i<=199;i++) b[i]=c[i],c[i]=0; 32 } 33 int main(){ 34 scanf("%d",&p); 35 printf("%d\n",(int)(log10(2)*p+1)); 36 a[0]=1,b[0]=2; 37 while(p){ 38 if(p&1) rid1(); 39 rid2(); 40 p=p>>1; 41 } 42 a[0]--; 43 for(int i=199,j=1;i>=0;i--,j++){ 44 write(a[i],5); 45 if(j%10==0) putchar('\n'); 46 } 47 return 0; 48 }
题目来源:洛谷,CODE[VS]