2^x mod n = 1(歐拉定理,歐拉函數,快速冪乘)

2^x mod n = 1

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 9231    Accepted Submission(s): 2837


ios

Problem Description
Give a number n, find the minimum x(x>0) that satisfies 2^x mod n = 1.
 

 

Input
One positive integer on each line, the value of n.
 

 

Output
If the minimum x exists, print a line with 2^x mod n = 1.

Print 2^? mod n = 1 otherwise.

You should replace x and n with specific numbers.
 
思路:
1. 當n爲偶數時,bn + 1(b爲整數)是奇數,而2^x是偶數,故 2^x mod n = 1不可能成立;
2. 當n等於1時,不能成立
3. 當n爲非1的奇數時,n和2互質,由歐拉定理:若a,n爲正整數,且二者互素,則a^phi(n) mod n = 1,其中phi(n)是n的歐拉函數。知2^phi(n) mod n = 1.所以phi(n)必是符合要求的x,但phi(n)未必是最小的,遍歷小於其的正整數,逐一試驗便可,計算2^x mod n時用快速冪乘。
 
AC Code:
 1 #include <iostream>
 2 #include <vector>
 3 #include <cstdio>
 4 #include <algorithm>
 5 #include <cstring>
 6 using namespace std;
 7 
 8 //計算n的歐拉函數
 9 int Eular(int n)
10 {
11     int res = 1, i;
12     for (i = 2; i * i <= n; i++){
13         if (n % i == 0){
14             n /= i;
15             res *= (i - 1);
16             while (n % i == 0){
17                 n /= i;
18                 res *= i;
19             }
20         }
21     }
22     if (n > 1) res *= (n - 1);
23     return res;
24 }
25 
26 //快速冪乘計算2^b % n
27 int myPow(int b, int n)  
28 {
29     if(b == 0) return 1;
30     long long c = myPow(b >> 1, n);
31     c = (c * c) % n;
32     if(b & 1) c = (2 * c) % n;
33     return c;
34 }
35 
36 int main()
37 {
38     int n, x;
39     bool ok;
40     while(scanf("%d", &n) != EOF){
41         ok = 0;
42         if((n & 1) && (n - 1)){
43             ok = 1;
44             int phi = Eular(n);
45             for(x = 1; x < phi; x++){
46                 if(myPow(x, n) == 1) break;
47             }
48         }
49         if(ok) printf("2^%d mod %d = 1\n", x, n);
50         else printf("2^%? mod %d = 1\n", n);
51     }
52     return 0;
53 }
相關文章
相關標籤/搜索