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.
Prime | Corresponding Mersenne Number |
---|---|
2 | 4–1 = 3 -- prime |
3 | 8–1 = 7 -- prime |
5 | 32–1 = 31 -- prime |
7 | 128–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 ) - 1233 * 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; }