原根(扩展欧几里得+欧拉函数)
设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 }
转载请注明出处:http://www.cnblogs.com/yuyixingkong/
自己命运的掌控着!