Give a number n, find the minimum x 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.
#include <iostream>
using namespace std;
#include<cmath>
class Fn {
public:
int X(int n) {
if (n == 1) return 0;
if (n % 2 == 0 && n != 2) return -1;
int x = 1;
long long a = 2;
while (a % n != 1) {
x++;
a = (a * 2) % n;
if (a== 0) return -1;
if (x > n) return -1;
}
return x;
}
};
int main() {
Fn b;
int n;
while (cin >> n) {
int x = b.X(n);
if (x != -1) {
cout << "2^" << x << " mod " << n << " = 1" << endl;
}
else {
cout << "2^? mod " << n << " = 1" << endl;
}
}
return 0;
}
首先,定义了一个名为Fn
的类,其中有一个公共成员函数X(int n)
。这个函数的目标是计算最小的正整数x
,使得2^x mod n = 1
成立,如果不存在这样的x
(意味着2
不是模n
下的原根),则返回-1。
函数X(int n)
的工作原理如下:
- 当输入的
n
为1时,根据模运算性质,直接返回0,因为2^0 mod 1 = 1。 - 若
n
为偶数且不等于2(因为2本身就是模2下的原根),则返回-1,因为在模非2的偶数下,2的任何次幂都不会得到1(总是0)。 - 初始化计数变量
x
为1,计算变量a
为2(即2^1)。 - 进入一个while循环,循环条件是
a
模n
不等于1。在循环内部:- 将
x
自增1。 - 更新
a
的值,令a
等于a * 2
再模n
,这样a
就变成了2^(x+1) mod n
。 - 如果发现
a
变为0,说明2^n被n整除,根据欧拉定理,这种情况不会出现2^x mod n = 1的情况,所以返回-1。 - 如果
x
的值超过了n
,也表明没有找到满足条件的x
,因此返回-1。
- 将
- 当循环结束时,说明找到了满足
2^x mod n = 1
的最小x
,返回x
。
在main
函数中:
- 创建一个
Fn
类的对象b
。 - 从标准输入读取整数
n
。 - 调用
b.X(n)
计算所需的x
值。 - 根据
X
函数的返回值,输出相应的信息。如果返回值不是-1,则输出“2^x mod n = 1”,否则输出“2^? mod n = 1”。不断循环直到用户停止输入。