P1045 麦森数 题解
首先,我们来思考如何计算
设
变形可以得到:
根据对数的运算法则又可以进行一次变形:
故其位数为
可以使用库函数:
log10(x)
接下来考虑如何计算
大家都知道,对于
若
那么我们就可以写出:
//这里是计算a的b次方对mod取余的结果。
long long quick_pow(long long a,long long b,long long mod){
long long res=1; //因为是幂运算,res要是1不能是0
while(b){
if(b&1) res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
因为是高精度,所以这里有几个地方要修改,修改过后的代码:
void quick_pow(int p){
res[0]=1,a[0]=2;
while(p){
if(p&1) multiply1(); //高精度乘法1
multiply2(); //高精度乘法2
p>>=1;
}
}
这个问题就完美地解决了。最后需要注意是 50 个为一行。
Code
#include<bits/stdc++.h>
int n,a[1010],res[1010],cnt;
void multiply1(){ //高精度乘法模板1
int tmp[1010]={0};
for(int i=0;i<500;i++){
for(int j=0;j<500;j++) tmp[i+j]+=res[i]*a[j];
}
int t=0;
for(int i=0;i<500;i++){
tmp[i]+=t;
res[i]=tmp[i]%10;
t=tmp[i]/10;
}
}
void multiply2(){ //高精度乘法模板2
int tmp[1010]={0};
for(int i=0;i<500;i++){
for(int j=0;j<500;j++) tmp[i+j]+=a[i]*a[j];
}
int t=0;
for(int i=0;i<500;i++){
tmp[i]+=t;
a[i]=tmp[i]%10;
t=tmp[i]/10;
}
}
void quick_pow(int p){ //快速幂
res[0]=1,a[0]=2;
while(p){
if(p&1) multiply1();
multiply2();
p>>=1;
}
}
int main(){
scanf("%d",&n);
int length=n*log10(2)+1;
printf("%d\n",length);
quick_pow(n);
res[0]-=1; //为什么能减1?因为不可能退位
for(int i=499;i>=0;i--){
if(cnt==50) printf("\n"),cnt=0; //每50个要记得换行
printf("%d",res[i]);
cnt++;
}
return 0;
}