【poj 1284】Primitive Roots(数论--欧拉函数 求原根个数){费马小定理、欧拉定理}
题意:求奇质数 P 的原根个数。若 x 是 P 的原根,那么 x^k (k=1~p-1) 模 P 为1~p-1,且互不相同。 (3≤ P<65536)
解法:有费马小定理:若 p 是质数,x^(p-1)=1 (mod p)。这和求原根有一定联系。
再顺便提一下欧拉定理:若 a,n 互质,那么 a^Φ(n)=1(mod n)。
还有一个推论:若x = y(mod φ(n) 且 a与n 互质,则有 a^x=a^y(mod n)。
百度百科是这么说的:“原根,归根到底就是 x^(p-1)=1 (mod p)当且仅当指数为 p-1 的时候成立。” 除了暴力求解找规律,就有这么一个性质:奇质数 p 的原根个数就是 Φ(p-1) 。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 using namespace std; 6 #define P 65600 7 8 int pr=0; 9 int prim[P],vis[P],phi[P]; 10 11 void get_prime() 12 { 13 memset(vis,0,sizeof(vis)); 14 for (int i=2;i<=P-10;i++) 15 { 16 if (!vis[i]) 17 { 18 prim[++pr]=i; 19 phi[i]=i-1; 20 } 21 for (int j=1;j<=pr && i*prim[j]<=P-10;j++) 22 { 23 vis[i*prim[j]]=1; 24 if (i%prim[j]!=0) phi[i*prim[j]]=phi[i]*phi[prim[j]]; 25 else 26 { 27 phi[i*prim[j]]=phi[i]*prim[j]; 28 break; 29 } 30 } 31 } 32 } 33 int main() 34 { 35 get_prime(); 36 int p,T=0; 37 while (scanf("%d",&p)!=EOF) 38 printf("%d\n",phi[p-1]); 39 return 0; 40 }