形如 的素数称为麦森数,这时 必定也是个素数。但反过来不必定,即若是 是个素数, 不必定也是素数。到 年末,人们已找到了 个麦森数。最大的一个是 ,它有 位。麦森数有许多重要应用,它与彻底数密切相关。html
任务:从文件中输入 ( ),计算 的位数和最后 位数字(用十进制高精度数表示)c++
文件中只包含一个整数 ( )web
第一行:十进制高精度数 的位数。app
第 行:十进制高精度数 的最后 位数字。(每行输出 位,共输出 行,不足 位时高位补 )svg
没必要验证 与 是否为素数。spa
1279
386 00000000000000000000000000000000000000000000000000 00000000000000000000000000000000000000000000000000 00000000000000104079321946643990819252403273640855 38615262247266704805319112350403608059673360298012 23944173232418484242161395428100779138356624832346 49081399066056773207629241295093892203457731833496 61583550472959420547689811211693677147548478866962 50138443826029173234888531116082853841658502825560 46662248318909188018470682222031405210266984354887 32958028878050869736186900714720710555703168729087
对于第一问,咱们要求 的位数,实质上就是求 的位数,由于 的末尾数不多是 ,那么怎么求 的位数呢.net
由于 的位数就是 code
那么,只要将底数 改为 就能够算了。xml
由于 htm
因此
那么 的位数就是
第一问就能够解决了。
对于第二问,直接高精度+快速幂
#include<bits/stdc++.h> using namespace std; int p; int cnt[1001],ans[1001]; int t[1001]; void t1(){ memset(t,0,sizeof(t)); for(int i=1;i<=500;i++){ for(int j=1;j<=500;j++){ t[i+j-1]+=cnt[i]*ans[j]; } } memset(ans,0,sizeof(ans));//清空 for(int i=1;i<=500;i++){ t[i+1]+=t[i]/10; t[i]%=10; ans[i]=t[i]; } } void t2(){ memset(t,0,sizeof(t)); for(int i=1;i<=500;i++){ for(int j=1;j<=500;j++){ t[i+j-1]+=cnt[i]*cnt[j]; } } memset(cnt,0,sizeof(cnt));//清空 for(int i=1;i<=500;i++){//单独处理进位 t[i+1]+=t[i]/10; t[i]%=10; cnt[i]=t[i]; } } int main(){ scanf("%d",&p); printf("%d",int(log10(2)*p+1));//第一问 cnt[1]=2;//初值2^1 ans[1]=1;//初值为1,由于要乘起来的 while(p){//快速幂模板 if(p&1)t1(); t2(); p>>=1; } ans[1]--; for(int i=500;i>=1;i--){ if(i%50==0)printf("\n");//50位一行 printf("%d",ans[i]); } return 0; }