题目链接:https://www.luogu.org/problemnew/show/P1045
题目描述
形如2^P-1的素数称为麦森数,这时P一定也是个素数。但反过来不一定,即如果PP是个素数,2^P-1不一定也是素数。到1998年底,人们已找到了37个麦森数。最大的一个是P=3021377,它有909526位。麦森数有许多重要应用,它与完全数密切相关。
任务:从文件中输入P(1000<P<3100000),计算2^P-1的位数和最后500位数字(用十进制高精度数表示)
输入输出格式
输入格式:
文件中只包含一个整数P(1000<P<3100000)
输出格式:
第一行:十进制高精度数2^P-1的位数。
第2-11行:十进制高精度数2^P-1的最后500位数字。(每行输出50位,共输出10行,不足500位时高位补0)
不必验证2^P-1与P是否为素数。
扫描二维码关注公众号,回复:
5632675 查看本文章
![](/qrcode.jpg)
输入输出样例
输入样例#1:
1279
输出样例#1:
对于求2^p的位数可以转化为求10^q的位数。
2^p=10^q
q=p*log102
2^p的位数就为q+1
后500位就直接用数组模拟
#include<iostream> #include<algorithm> #include<cmath> using namespace std; #define ll long long int p,len,a[1000]; ll poww(ll x,ll y) { ll ans=1; while(y) { if(y&1)ans*=x; x*=x; y/=2; } return ans; } int main() { cin>>p; len=p*log10(2)+1;//math自带log10函数 ll cnt1=p/20,cnt2=p%20,q=poww(2,20); cout<<len<<endl; a[1]=1; for(int i=1;i<=cnt1;i++) { for(int j=1;j<=500;j++) a[j]*=q; for(int j=1;j<=500;j++) { a[j+1]+=a[j]/10; a[j]=a[j]%10; } } for(int i=1;i<=cnt2;i++) { for(int j=1;j<=500;j++) a[j]*=2; for(int j=1;j<=500;j++) { a[j+1]+=a[j]/10; a[j]=a[j]%10; } } a[1]--; int cnt=0; for(int i=500;i>=1;i--) { cout<<a[i]; cnt++; if(cnt%50==0)cout<<endl; } return 0; }