原根(扩展欧几里得+欧拉函数)

基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题
 
设m是正整数,a是整数,若a模m的阶等于φ(m),则称a为模m的一个原根。(其中φ(m)表示m的欧拉函数)
 
给出1个质数P,找出P最小的原根。
Input
输入1个质数P(3 <= P <= 10^9)
Output
输出P最小的原根。
Input示例
3
Output示例
2


转载请注明出处:寻找&星空の孩子

题目链接
:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1135
 1 //求最小原根
 2 #include <iostream>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <cstdio>
 6 #define ll __int64
 7 using namespace std;
 8 int P;
 9 const int NUM = 100001;
10 int prime[NUM/4];
11 bool f[NUM];
12 int pNum = 0;
13 void getPrime()//线性筛选素数
14 {
15     for (int i = 2; i < NUM; ++ i)
16     {
17         if (!f[i])
18         {
19             f[i] = 1;
20             prime[pNum++] = i;
21         }
22         for (int j = 0; j < pNum && i*prime[j] < NUM; ++ j)
23         {
24             f[i*prime[j]] = 1;
25             if (i%prime[j] == 0)
26             {
27                 break;
28             }
29         }
30     }
31 }
32 ll ppow(ll a,ll b,ll mod)
33 {
34     ll c=1;
35     while(b)
36     {
37         if(b&1) c=c*a%mod;
38         b>>=1;
39         a=a*a%mod;
40     }
41     return c;
42 }
43 
44 bool judge(int num)//求num的所有的质因子
45 {
46     int elem[1000];
47     int elemNum = 0;
48     int k = P - 1;
49     for (int i = 0; i < pNum; ++ i)
50     {
51         bool flag = false;
52         while (!(k%prime[i]))
53         {
54             flag = true;
55             k /= prime[i];
56         }
57         if (flag)
58         {
59             elem[elemNum ++] = prime[i];
60         }
61         if (k==1)
62         {
63             break;
64         }
65         if (k/prime[i]<prime[i])
66         {
67             elem[elemNum ++] = prime[i];
68             break;
69         }
70     }
71     bool flag = true;
72     for (int i = 0; i < elemNum; ++ i)
73     {
74         if (ppow(num,(P-1)/elem[i],P) == 1)
75         {
76             flag = false;
77             break;
78         }
79     }
80     return flag;
81 }
82 int main()
83 {
84     getPrime();
85     while (scanf("%d",&P)!=EOF)
86     {
87         int i=2;
88         while(!judge(i))i++;
89         printf("%d\n",i);
90     }
91     return 0;
92 }

 




posted @ 2015-08-12 00:12  寻找&星空の孩子  阅读(1218)  评论(0编辑  收藏  举报