SOJ 1009

1009. Mersenne Composite N

Constraints

Time Limit: 1 secs, Memory Limit: 32 MB

Description

One of the world-wide cooperative computing tasks is the "Grand Internet Mersenne Prime Search" -- GIMPS -- striving to find ever-larger prime numbers by examining a particular category of such numbers. 
A Mersenne number is defined as a number of the form (2p–1), where p is a prime number -- a number divisible only by one and itself. (A number that can be divided by numbers other than itself and one are called "composite" numbers, and each of these can be uniquely represented by the prime numbers that can be multiplied together to generate the composite number — referred to as its prime factors.) 
Initially it looks as though the Mersenne numbers are all primes. 

PrimeCorresponding Mersenne Number
24–1 = 3 -- prime
38–1 = 7 -- prime
532–1 = 31 -- prime
7128–1 = 127 -- prime

If, however, we are having a "Grand Internet" search, that must not be the case. 
Where k is an input parameter, compute all the Mersenne composite numbers less than 2 k  -- where k <= 63 (that is, it will fit in a 64-bit signed integer on the computer). In Java, the "long" data type is a signed 64 bit integer. Under gcc and g++ (C and C++ in the programming contest environment), the "long long" data type is a signed 64 bit integer.

Input

Input is from file a. in. It contains a single number, without leading or trailing blanks, giving the value of k. As promised, k <= 63.

Output

One line per Mersenne composite number giving first the prime factors (in increasing order) separate by asterisks, an equal sign, the Mersenne number itself, an equal sign, and then the explicit statement of the Mersenne number, as shown in the sample output. Use exactly this format. Note that all separating white space fields consist of one blank.

Sample Input

31

Sample Output

23 * 89 = 2047 = ( 2 ^ 11 ) - 1
47 * 178481 = 8388607 = ( 2 ^ 23 ) - 1

233 * 1103 * 2089 = 536870911 = ( 2 ^ 29 ) - 1

题目输入一个p值,对于不大于p的每个素数x,要先判断2^x-1是否和素数,不是的话再求出它的质因子。下面的做法有点作弊嫌疑,我是直接百度梅森素数查到的哪些x值是素数,哪些是合数,所以就省去了判断的步骤,其实判断大数是否为素数也有点技巧性,直接依次取余肯定是超时的,可以用Robin-Miller算法来判断素数。

判断出是合数后,就可以用迭代法从小到大求出质因子,然后按格式输出就行了。

// Problem#: 1009
// Submission#: 4930576
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include<iostream>
#include <vector>
#include<cmath>
#include<algorithm>
using namespace std;

vector<long long> prifactor(int p)//返回一个容器对象,保存了从小到大的质因子 
{
    long long n=pow(2,p)-1;
    vector<long long> factor;
    for(long long i=2;i*i<=n;++i)
    {
        while(n%i==0)
        {
            n/=i;
            factor.push_back(i);
        }
    }
    if(n!=1)//1不是质数,所以不能把1放进去 
    factor.push_back(n);
    return factor; 
}

int main()
{
    int p;
    cin>>p; 
    int comMersen[]={11,23,29,37,41,43,47,53,59};//百度梅森素数,直接查到的当p=11、23、29……时2^p-1是合数 
    for(int i=2;i<=p;++i)
    {
        long long n=pow(2,i)-1;
            int *a=find(comMersen,comMersen+9,i);//用find函数查找看i是否在comMersen数组里,在的话则说明2^i-1是合数 
            if(a!=comMersen+9) 
            {
                vector<long long> vec=prifactor(i);
                for(int j=0;j<vec.size()-1;++j)
                cout<<vec[j]<<" "<<'*'<<" ";
                cout<<vec[vec.size()-1]<<" "<<'='<<" "<<n<<" "<<'='<<" "<<'('<<" "<<2;
                cout<<" "<<'^'<<" "<<i<<" "<<')'<<" "<<'-'<<" "<<1<<endl;
                
            }
        
    }
    return 0;
}                                 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值