题目描述
形如2^p-1的素数称为麦森数,这时p一定也是个素数。但反过来不一定,即如果p是个素数,2^p-1不一定也是素数。 到1998年底,人们已找到了37个麦森数。最大的一个是p=3021377,它有909526位。 麦森数有许多重要应用,它与完全数密切相关。 现要求输入p(1000< P < 3100000),计算2^p-1的位数和最后500位数字(用十进制高精度数表示)。
输入
第1行:1个整数p(1000<p<3100000)< div="">
输出
第1行:十进制高精度数2^p-1的位数; 第2..11行:十进制高精度数2^p-1的最后500位数字(每行输出50位,共输出10行,不足500位时高位补0); 注意:不必验证2^p-1与p是否为素数。
样例输入
(如果复制到控制台无换行,可以先粘贴到文本编辑器,再复制)
1279
样例输出
386
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
38615262247266704805319112350403608059673360298012
00000000000000104079321946643990819252403273640855
23944173232418484242161395428100779138356624832346
50138443826029173234888531116082853841658502825560
49081399066056773207629241295093892203457731833496
61583550472959420547689811211693677147548478866962
46662248318909188018470682222031405210266984354887
32958028878050869736186900714720710555703168729087
分析:
重定义运算符+快速幂
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#define LL long long
using namespace std;
//#define BIG 100000LL
const LL BIG=100000LL;
struct INT{
LL data[500];
int len;
INT(){memset(data,0,sizeof(data));len=0;}
void operator=(int x){
while(x){
data[len++]=x%BIG;
x/=BIG;
}
}
}ans,tmp;
int p;
INT operator*(const INT &a,const INT &b){
INT ret;
int i, j, add;
for(i=0;i<a.len&&i<100;i++){
add=0;
for(j=0;j<b.len&&j<100;j++)
if(i+j<100){
ret.data[i+j]+=a.data[i]*b.data[j]+add;
if((add=ret.data[i+j]/BIG))
ret.data[i+j]%=BIG;
}
if(i+j<100)
ret.data[i+j]+=add;
}
int len=i+j-1;
if(add&&len<100)
ret.data[len++]=add;
ret.len=len;
return ret;
}
void work(){
int t=p;
ans=1;tmp=2;
while(t){
if(t&1)ans=ans*tmp;
t>>=1;
tmp=tmp*tmp;
}
}
int main(){
int i;
scanf("%d",&p);
printf("%d\n",int(log10(2)*p)+1);
work();
ans.data[0]--;
for(i=99;i>=0;i--){
printf("%05lld",ans.data[i]);
if(i%10==0)
printf("\n");
}
}
题目描述
形如2^p-1的素数称为麦森数,这时p一定也是个素数。但反过来不一定,即如果p是个素数,2^p-1不一定也是素数。 到1998年底,人们已找到了37个麦森数。最大的一个是p=3021377,它有909526位。 麦森数有许多重要应用,它与完全数密切相关。 现要求输入p(1000< P < 3100000),计算2^p-1的位数和最后500位数字(用十进制高精度数表示)。
输入
第1行:1个整数p(1000<p<3100000)< div="">
输出
第1行:十进制高精度数2^p-1的位数; 第2..11行:十进制高精度数2^p-1的最后500位数字(每行输出50位,共输出10行,不足500位时高位补0); 注意:不必验证2^p-1与p是否为素数。
样例输入
(如果复制到控制台无换行,可以先粘贴到文本编辑器,再复制)
1279
样例输出
386
00000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000
38615262247266704805319112350403608059673360298012
00000000000000104079321946643990819252403273640855
23944173232418484242161395428100779138356624832346
50138443826029173234888531116082853841658502825560
49081399066056773207629241295093892203457731833496
61583550472959420547689811211693677147548478866962
46662248318909188018470682222031405210266984354887
32958028878050869736186900714720710555703168729087
分析:
重定义运算符+快速幂
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#define LL long long
using namespace std;
//#define BIG 100000LL
const LL BIG=100000LL;
struct INT{
LL data[500];
int len;
INT(){memset(data,0,sizeof(data));len=0;}
void operator=(int x){
while(x){
data[len++]=x%BIG;
x/=BIG;
}
}
}ans,tmp;
int p;
INT operator*(const INT &a,const INT &b){
INT ret;
int i, j, add;
for(i=0;i<a.len&&i<100;i++){
add=0;
for(j=0;j<b.len&&j<100;j++)
if(i+j<100){
ret.data[i+j]+=a.data[i]*b.data[j]+add;
if((add=ret.data[i+j]/BIG))
ret.data[i+j]%=BIG;
}
if(i+j<100)
ret.data[i+j]+=add;
}
int len=i+j-1;
if(add&&len<100)
ret.data[len++]=add;
ret.len=len;
return ret;
}
void work(){
int t=p;
ans=1;tmp=2;
while(t){
if(t&1)ans=ans*tmp;
t>>=1;
tmp=tmp*tmp;
}
}
int main(){
int i;
scanf("%d",&p);
printf("%d\n",int(log10(2)*p)+1);
work();
ans.data[0]--;
for(i=99;i>=0;i--){
printf("%05lld",ans.data[i]);
if(i%10==0)
printf("\n");
}
}
题目描述
形如2^p-1的素数称为麦森数,这时p一定也是个素数。但反过来不一定,即如果p是个素数,2^p-1不一定也是素数。 到1998年底,人们已找到了37个麦森数。最大的一个是p=3021377,它有909526位。 麦森数有许多重要应用,它与完全数密切相关。 现要求输入p(1000< P < 3100000),计算2^p-1的位数和最后500位数字(用十进制高精度数表示)。
输入
第1行:1个整数p(1000<p<3100000)< div="">
输出
第1行:十进制高精度数2^p-1的位数; 第2..11行:十进制高精度数2^p-1的最后500位数字(每行输出50位,共输出10行,不足500位时高位补0); 注意:不必验证2^p-1与p是否为素数。
样例输入
(如果复制到控制台无换行,可以先粘贴到文本编辑器,再复制)
1279
样例输出
38600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003861526224726670480531911235040360805967336029801200000000000000104079321946643990819252403273640855239441732324184842421613954281007791383566248323465013844382602917323488853111608285384165850282556049081399066056773207629241295093892203457731833496 61583550472959420547689811211693677147548478866962 4666224831890918801847068222203140521026698435488732958028878050869736186900714720710555703168729087
分析:
重定义运算符+快速幂
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#define LL long long
using namespace std;
//#define BIG 100000LL
const LL BIG=100000LL;
struct INT{
LL data[500];
int len;
INT(){memset(data,0,sizeof(data));len=0;}
void operator=(int x){
while(x){
data[len++]=x%BIG;
x/=BIG;
}
}
}ans,tmp;
int p;
INT operator*(const INT &a,const INT &b){
INT ret;
int i, j, add;
for(i=0;i<a.len&&i<100;i++){
add=0;
for(j=0;j<b.len&&j<100;j++)
if(i+j<100){
ret.data[i+j]+=a.data[i]*b.data[j]+add;
if((add=ret.data[i+j]/BIG))
ret.data[i+j]%=BIG;
}
if(i+j<100)
ret.data[i+j]+=add;
}
int len=i+j-1;
if(add&&len<100)
ret.data[len++]=add;
ret.len=len;
return ret;
}
void work(){
int t=p;
ans=1;tmp=2;
while(t){
if(t&1)ans=ans*tmp;
t>>=1;
tmp=tmp*tmp;
}
}
int main(){
int i;
scanf("%d",&p);
printf("%d\n",int(log10(2)*p)+1);
work();
ans.data[0]--;
for(i=99;i>=0;i--){
printf("%05lld",ans.data[i]);
if(i%10==0)
printf("\n");
}
}