暴力搞肯定不行,因此我们从小到大枚举素数,用n去试除,每次除尽,如果已经超过20,肯定是no。如果当前枚举到的素数的(20-已经找到的质因子个数)次方>剩下的n,肯定也是no。再加一个关键的优化,如果剩下的次数是1了,就直接判定剩下的n是否是素数。这样可以保证次方>=2,将我们需要枚举的素数限制在200w以内,就可做了。线性筛在这题虽然不必要,但是可以当个板子存下来。
Input
Output
Example
input | output |
---|---|
2 |
No |
1048576 |
Yes |
10000000000 |
Yes |
#include<cstdio> #include<cmath> using namespace std; typedef long long ll; #define MAXP 2000000 #define EPS 0.00000001 ll n; bool isNotPrime[MAXP+10]; int num_prime,prime[MAXP+10]; void shai() { for(long i = 2 ; i < MAXP ; i ++) { if(! isNotPrime[i]) prime[num_prime ++]=i; for(long j = 0 ; j < num_prime && i * prime[j] < MAXP ; j ++) { isNotPrime[i * prime[j]] = 1; if( !(i % prime[j])) break; } } } bool is_prime(ll x) { if(x==1ll) return 0; for(ll i=2;i*i<=x;++i) if(x%i==0) return 0; return 1; } int m=20; int main() { scanf("%I64d",&n); shai(); for(int i=0;i<num_prime;++i) { if((double)m*log((double)prime[i])-log((double)n)>EPS) { puts("No"); return 0; } while(n%(ll)prime[i]==0) { n/=(ll)prime[i]; --m; } if(m==0 && n==1) { puts("Yes"); return 0; } if(m<0 || (m==0 && n>1)) { puts("No"); return 0; } if(n>1 && m==1) { if(is_prime(n)) { puts("Yes"); return 0; } else { puts("No"); return 0; } } } return 0; }
【线性筛】【筛法求素数】【素数判定】URAL - 2102 - Michael and Cryptography
原文:http://www.cnblogs.com/autsky-jadek/p/6304319.html