题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=1395
题目大意:
题目中给出输入一个整数n,要求一个最小整数的x,使得2^x mod n=1;
解题思路:
2^x = 1(mod n)就是求2模上n的阶。
如果n是偶数或者是1,答案一定不存在
如果是偶数,2^x也是偶数,偶数模上偶数不可能为1。
如果n为1,那么模的结果一定为0。
如果n是奇数,那么可以求阶,也可以暴力(数据水)
求阶的方法:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 int a[10005]; 5 int euler_phi(int n)//求单个 6 { 7 int m = (int)sqrt(n + 0.5); 8 int ans = n; 9 for(int i = 2; i <= m; i++)if(n % i == 0) 10 { 11 ans = ans / i * (i - 1); 12 while(n % i == 0)n /= i; 13 } 14 if(n > 1)ans = ans / n * (n - 1); 15 return ans; 16 } 17 ll pow(ll a, ll b, ll m) 18 { 19 a %= m; 20 ll ans = 1; 21 while(b) 22 { 23 if(b & 1)ans = ans * a % m; 24 a = a * a % m; 25 b /= 2; 26 } 27 return ans % m; 28 } 29 int main() 30 { 31 int n; 32 while(cin >> n) 33 { 34 int tot = 0; 35 if(n % 2 == 0 || n == 1) 36 { 37 printf("2^? mod %d = 1 ", n); 38 continue; 39 } 40 int t = euler_phi(n); 41 //cout<<t<<endl; 42 for(int i = 1; i * i <= t; i++) 43 { 44 if(t % i == 0) 45 { 46 a[tot++] = i; 47 if(i * i != t)a[tot++] = t / i; 48 } 49 } 50 sort(a, a + tot); 51 //for(int i = 0; i < tot; i++)printf("%d ", a[i]); 52 for(int i = 0; i < tot; i++) 53 { 54 if(pow(2, a[i], n) == 1) 55 { 56 printf("2^%d mod %d = 1 ", a[i], n); 57 break; 58 } 59 } 60 } 61 return 0; 62 }