麦森数
题目描述
形如2P-1的素数称为麦森数,这时P一定也是个素数。但反过来不一定,即如果P是个素数,2P-1不一定也是素数。到1998年底,人们已找到了37个麦森数。最大的一个是P=3021377,它有909526位。麦森数有许多重要应用,它与完全数密切相关。
任务:从文件中输入P(1000<P<3100000),计算2P-1的位数和最后500位数字(用十进制高精度数表示)。
输入
每组输入只包含一个整数P(1000<P<3100000)。
输出
第一行:十进制高精度数2P-1的位数。
第2-11行:十进制高精度数2P-1的最后500位数字。(每行输出50位,共输出10行,不足500位时高位补0)
不必验证2P-1与P是否为素数。
样例输入 Copy
1279
样例输出 Copy
386
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
00000000000000104079321946643990819252403273640855
38615262247266704805319112350403608059673360298012
23944173232418484242161395428100779138356624832346
49081399066056773207629241295093892203457731833496
61583550472959420547689811211693677147548478866962
50138443826029173234888531116082853841658502825560
46662248318909188018470682222031405210266984354887
32958028878050869736186900714720710555703168729087
来源/分类
题解:题目要求只让求后500位的数字,所以我们就开一个500的数组,前边的数不用管。比赛时主要卡在两个点上
1、我们用大数写的求的是所有的位数,但因为数据太大,所以超时
2、后来我们限制了一下只计算后500位,但我们不会求2的n次方的位数,这其实就是一个公式n*(log2)+1
#include<cstdio>
#include<cstring>
#include<math.h>
#include<iostream>
#include<iomanip>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<algorithm>
using namespace std;
#define debug(x) printf("%d***\n",x)
#define ll long long
#define maxn 100000
#define inf 0x3f3f3f3f
#define mod 1000000007
const double pi=acos(-1.0);
string sum(string s1,string s2) //大数加法
{
if(s1.length()<s2.length())
{
string temp=s1;
s1=s2;
s2=temp;
}
int i,j;
for(i=s1.length()-1,j=s2.length()-1; i>=0; i--,j--)
{
s1[i]=char(s1[i]+(j>=0?s2[j]-'0':0));
if(s1[i]-'0'>=10)
{
s1[i]=char((s1[i]-'0')%10+'0');
if(i) s1[i-1]++;
else s1='1'+s1;
}
}
return s1;
}
string mult(string s,int x)
{
reverse(s.begin(),s.end());
int cmp=0;
int cccc=0;
int dddd=s.size()-500;
for(int i=max(cccc,dddd); i<s.size(); i++)
{
cmp=(s[i]-'0')*x+cmp;
s[i]=(cmp%10+'0');
cmp/=10;
}
while(cmp)
{
s+=(cmp%10+'0');
cmp/=10;
}
reverse(s.begin(),s.end());
return s;
}
string multfa(string x,string y)
{
string ans;
int cnt=500;
int llll=y.size()-1;
for(int i=min(cnt,llll),j=0; i>=0; i--,j++)
{
string tmp=mult(x,y[i]-'0');
for(int k=0; k<j; k++)
tmp+='0';
ans=sum(ans,tmp);
}
return ans;
}
string subinfo(string s1,string s2)
{
int a[maxn],b[maxn];
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
int l1=s1.size(),l2=s2.size();
int maxl=max(l1,l2);
for(int i=0; i<l1; i++)
a[i]=s1[l1-i-1]-'0';
for(int i=0; i<l2; i++)
b[i]=s2[l2-i-1]-'0';
for(int i=0; i<maxl; i++)
{
if(a[i]-b[i]<0)
{
a[i]=a[i]+10-b[i];
a[i+1]-=1;
}
else a[i]-=b[i];
}
string str="";
int i;
for(i=maxl-1; i>=0; i--)
if(a[i]!=0) break;
for(; i>=0; i--) str+=a[i]+'0';
return str;
}
string bigsub(string s1,string s2)
{
if(s1==s2)
return "0";
int l1=s1.size(),l2=s2.size();
if(l1>l2)
return subinfo(s1,s2);
else if(l1<l2)
return "-"+subinfo(s2,s1);
else
{
for(int i=0; i<l1; i++)
{
if(s1[i]-'0'>s2[i]-'0')
return subinfo(s1,s2);
else if(s1[i]-'0'<s2[i]-'0');
return "-"+subinfo(s2,s1);
}
}
}
string powmi(string a,int b)
{
string ans="1";
while(b)
{
if(b%2==1)
ans=multfa(ans,a);
a=multfa(a,a);
b/=2;
}
return ans;
}
int main()
{
string a,ans1,p;
int b;
p="1";
a="2";
while(cin>>b)
{
ans1=bigsub(powmi(a,b),p);
int l=(int)(b*log10(2)+1);
cout<<l<<endl;
int kk=500-l;
int s=0;
if(kk>0)
{
for(int i=0; i<kk; i++,s++)
{
if(s==50)
{
s=0;
cout<<endl;
}
cout<<"0";
}
}
for(int i=max(l-500,0); i<l; i++,s++)
{
if(s==50)
{
s=0;
cout<<endl;
}
cout<<ans1[i];
}
cout<<endl;
}
return 0;
}