NOIP2003普及组 麦森数
题面
形如2p-1的素数被称为麦森数,这时P一定也是个素数。但反过来不一定,即P为素数时2p-1不一定是素数。到1998年年底,人们已经找到了37个麦森数。最大的一个是P=3021377,它有909526位。麦森数有许多重要运用,它与完全数密切相关。
任务:给定一个数P,求出它的后500位数和位数。
解:
1. 循环P次单精度计算
随着P的增大,数的位数也在增大,采用此方法易TLE
2. 快速幂+高精度计算
看上去是可行的,但是题目只要求我们得到后500位即可,如果只是为了求位数而牺牲太多时间也是不划算的。
3.快速幂+高精度500位计算+公式推导
在快速幂和高精度的基础上,我们每次只计算500位,大大的减少时间,那么因此位数的求法就很重要了。
(1)2的次方数的末位均为(2,4,8,6),减去1就不会造成退位,所以2p-1的位数等于2p。
(2)对于10X来说,这个数的位数一定是X+1,那我们就可以尝试着把2p转为10^X,不就可以求出位数了吗?
设10^y=2,则lg(2)=y
所以10^lg(2)=2
那么2p=(10lg(2))^p
因为(Xa)b=X^ab
所以2p=10(lg(2)*p)
因为10^X的位数为X+1
所以10(lg(2)*p)的位数应该为lg(2)*p+1,则2p或者2^p-1的位数为lg(2)*p+1
此时应注意向下取整。
在C++中的头文件math里,可以使用*log10(2)*。
#include<cstdio>
#include<cmath>
using namespace std;
int main(){
int p;
scanf("%d",&p);
int ans=(int)(log10(2)*p+1);
printf("%d",ans);
return 0;
}
这样我们就可以得到位数了。
至于后面的快速幂+高精度就很好解决了。