Description
命案现场,死者用血写了Mersenne_prime(x),这样一个式子,可是x这个整数已经难以识别了,只能分辨出应该是2~64的一个整数。
为了协助破案,柯南需要求出3~64的梅森数,并且要确定它们是不是梅森素数。
如果不是梅森素数,柯南还需要对他们进行质因数分解,以探求他们之间的规律。
Input
输入有多组,每组输入数据占一行,包含一个整数x,2<=x<=64。
Output
如果 y = 2x - 1 是一个梅森素数,则输出一行:“y is Mersenne prime.”,
否则输出两行,第一行输出:“y is NOT Mersenne prime.”,第二行用空格分开,由小到大输出所有质因子。
Sample Input
2
3
4
Sample Output
3 is Mersenne prime.
7 is Mersenne prime.
15 is NOT Mersenne prime.
3 5
有关麦森素数与求质因子的结合。
可以使用unsigned long long 表示更大的数据。
麦森数是形如2^p-1的数,
如果一个麦森数是素数,我们称之为麦森素数
现在发现的麦森素数有以下:
P2,P3,P5,P7,P13,P19,P31,P61,P89,P107,P127等等。
分解一个数的质因子及其个数的模板如下:
ULL getPrimeFactor(ULL num,ULL* fc)
{
ULL fcNum=0,j;
for(ULL j=2;j*j<=num;j++)
{
if(num%j)
continue;
fc[fcNum++]=j;
while(num%j==0)
num/=j;
}
if(num!=1)
fc[fcNum++]=num;
return fcNum;
}
有了以上基础知识后,本题就好做了,但是对于P=64和P=62时要单独处理,通过打表发现。原因是:1.数据太大。2.质因子太大,算法运行时间过长,会超时。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#define ULL unsigned long long
using namespace std;
ULL MSS[]={2,3,5,7,13,17,19,31,61};
ULL x;
ULL ZPrim[1001];
ULL y(ULL x)
{
return ((ULL)1<<x)-1;
}
ULL getPrimeFactor(ULL num,ULL* fc)
{
ULL fcNum=0,j;
for(ULL j=2;j*j<=num;j++)
{
if(num%j)
continue;
fc[fcNum++]=j;
while(num%j==0)
num/=j;
}
if(num!=1)
fc[fcNum++]=num;
return fcNum;
}
int main()
{
while(scanf("%lld",&x)!=EOF)
{
memset(ZPrim,0,sizeof(ZPrim));
bool flag=false;
for(int i=0;i<9;i++)
if(x==MSS[i])
flag=true;
if(flag)
printf("%lld is Mersenne prime.\n",y(x));
else
{
if(x==64)
{
printf("18446744073709551615 is NOT Mersenne prime.\n");
printf("3 5 17 257 641 65537 6700417\n");
}
else if(x==62)
{
printf("%lld is NOT Mersenne prime.\n",y(x));
printf("3 715827883 2147483647\n");
}
else
{
printf("%lld is NOT Mersenne prime.\n",y(x));
ULL k=getPrimeFactor(y(x),ZPrim);
printf("%lld",ZPrim[0]);
for(ULL i=1;i<k;i++)
printf(" %lld",ZPrim[i]);
printf("\n");
}
}
}
return 0;
}