【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 }

 

posted @ 2016-11-15 20:08  konjac蒟蒻  阅读(361)  评论(0编辑  收藏  举报