ACM ICPC 2017 Warmup Contest 9 I
I. Older Brother
Your older brother is an amateur mathematician with lots of experience. However, his memory is very bad. He recently got interested in linear algebra over finite fields, but he does not remember exactly which finite fields exist. For you, this is an easy question: a finite field of order q exists if and only if q is a prime power, that is, q = p^kpk holds for some prime number pand some integer k ≥ 1. Furthermore, in that case the field is unique (up to isomorphism).
The conversation with your brother went something like this:
Input
The input consists of one integer q, satisfying 1 ≤ q ≤ 10^9109.
Output
Output “yes” if there exists a finite field of order q. Otherwise, output “no”.
样例输入1
1
样例输出1
no
样例输入2
37
样例输出2
yes
样例输入3
65536
样例输出3
yes
题目来源
ACM ICPC 2017 Warmup Contest 9
题意:问一个数n是否是一个素数p的k次方
思路:用Pollard_rho分解质因数,看一看所有的质因子是否相等。
1 //2017-10-24 2 #include <cstdlib> 3 #include <iostream> 4 #include <ctime> 5 6 typedef long long LL; 7 #define MAXN 10000 8 9 using namespace std; 10 11 LL factor[MAXN]; 12 int tot; 13 const int S=20; 14 15 LL muti_mod(LL a,LL b,LL c){ //返回(a*b) mod c,a,b,c<2^63 16 a%=c; 17 b%=c; 18 LL ret=0; 19 while (b){ 20 if (b&1){ 21 ret+=a; 22 if (ret>=c) ret-=c; 23 } 24 a<<=1; 25 if (a>=c) a-=c; 26 b>>=1; 27 } 28 return ret; 29 } 30 31 LL pow_mod(LL x,LL n,LL mod){ //返回x^n mod c ,非递归版 32 if (n==1) return x%mod; 33 int bit[90],k=0; 34 while (n){ 35 bit[k++]=n&1; 36 n>>=1; 37 } 38 LL ret=1; 39 for (k=k-1;k>=0;k--){ 40 ret=muti_mod(ret,ret,mod); 41 if (bit[k]==1) ret=muti_mod(ret,x,mod); 42 } 43 return ret; 44 } 45 46 bool check(LL a,LL n,LL x,LL t){ //以a为基,n-1=x*2^t,检验n是不是合数 47 LL ret=pow_mod(a,x,n),last=ret; 48 for (int i=1;i<=t;i++){ 49 ret=muti_mod(ret,ret,n); 50 if (ret==1 && last!=1 && last!=n-1) return 1; 51 last=ret; 52 } 53 if (ret!=1) return 1; 54 return 0; 55 } 56 57 bool Miller_Rabin(LL n){ 58 LL x=n-1,t=0; 59 while ((x&1)==0) x>>=1,t++; 60 bool flag=1; 61 if (t>=1 && (x&1)==1){ 62 for (int k=0;k<S;k++){ 63 LL a=rand()%(n-1)+1; 64 if (check(a,n,x,t)) {flag=1;break;} 65 flag=0; 66 } 67 } 68 if (!flag || n==2) return 0; 69 return 1; 70 } 71 72 LL gcd(LL a,LL b){ 73 if (a==0) return 1; 74 if (a<0) return gcd(-a,b); 75 while (b){ 76 LL t=a%b; a=b; b=t; 77 } 78 return a; 79 } 80 81 //找出任意质因数 82 LL Pollard_rho(LL x,LL c){ 83 LL i=1,x0=rand()%x,y=x0,k=2; 84 while (1){ 85 i++; 86 x0=(muti_mod(x0,x0,x)+c)%x; 87 LL d=gcd(y-x0,x); 88 if (d!=1 && d!=x){ 89 return d; 90 } 91 if (y==x0) return x; 92 if (i==k){ 93 y=x0; 94 k+=k; 95 } 96 } 97 } 98 99 //递归进行质因数分解N 100 void findfac(LL n){ 101 if (!Miller_Rabin(n)){ 102 factor[tot++] = n; 103 return; 104 } 105 LL p=n; 106 while (p>=n) p=Pollard_rho(p,rand() % (n-1) +1); 107 findfac(p); 108 findfac(n/p); 109 } 110 111 int main(){ 112 int n; 113 while(cin>>n){ 114 if(n == 1){ 115 cout<<"no"<<endl; 116 continue; 117 } 118 tot = 0; 119 findfac(n); 120 bool ok = 1; 121 for(int i = 1; i < tot; i++) 122 if(factor[i] != factor[i-1]){ 123 ok = 0; 124 break; 125 } 126 if(ok)cout<<"yes"<<endl; 127 else cout<<"no"<<endl; 128 } 129 return 0; 130 }