hdu-1395 2^x mod n = 1---求阶(欧拉函数)

题目链接:

 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", 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\n", a[i], n);
57                 break;
58             }
59         }
60     }
61     return 0;
62 }

 

posted @ 2018-05-14 21:34  _努力努力再努力x  阅读(274)  评论(0编辑  收藏  举报