1、求乘法逆元以及求解同余方程ax = b mod m
具体题目如下:
实现求乘法逆元的函数,给定a和m,求a模m的乘法逆元,无解时请给出无解提示,并且只返回正整数。进而给出求解同余方程(ax = b mod m)的函数,即给定a,b,m,输出满足方程的x,无解给出无解提示。
下面程序均假设egcd函数已经实现
1.1 求乘法逆元
//实现求乘法逆元的函数
#include <iostream>
using namespace std;
int multi_inverse (int a, int m);
int main()
{
int a, m;
cin >> a >> m;
int Multi_Inverse = multi_inverse(a, m);
if (Multi_Inverse == -1)
cout << "无解" << endl;
else
cout << "逆元是" << Multi_Inverse;
}
//求a模m的乘法逆元
int multi_inverse (int a, int m)
{
int s, t;
//gcd(a,m)!=1 无解
if (egcd(a, m, &s, &t) != 1)
{
return -1;
}
//gcd(a,m)=1 此时有解,且逆元取决于a前面的系数
else
{
//又基于egcd函数会将大的输入数与s系数配对,小的输入数反之则与t配对,下面进行对a和m判断大小
if (a > m) //此时s即是a前面的系数
{
if (s < 0)
s = s + m;//根据逆元定义:负数要转化为正数
return s;
}
else //对此时t即是a前面的系数
{
if (t < 0)
t = t + m;
return t;
}
}
}
1.2 求解同余方程
#include <iostream>
using namespace std;
int solve_CongruenceEquation(int a, int b, int m);
int main()
{
int a, b, m;
cin >> a >> b >> m;
int x = solve_CongruenceEquation(a, b, m);
if (x == -1)
cout << "无解";
else
cout << "解为" << x;
}
//求解同余方程(ax = b mod m)的函数
int solve_CongruenceEquation(int a, int b, int m)
{
int x, y;
int gcd_a_m = egcd(a, m, &y, &x); //gcd(a,m)
//gcd(a,m)|b不成立,无解
if ((b % gcd_a_m) != 0)
{
return -1;
}
//gcd(a,m)|b 成立
else
{
return x / gcd_a_m * b;//这里输出的仅是其中一个特解
}
}
2、模指数运算
实现模指数运算的函数,给定x、y和m,求x的y次方模m。
//实现模指数运算的函数
#include <iostream>
using namespace std;
int mod_exp(int x, int y, int p);
int main()
{
int x, y, p;
cin >> x >> y >> p;
cout << mod_exp(x, y, p);
}
int mod_exp(int x, int y, int p)
{
int result = 1;
while (y > 0)
{
if ((y & 1) == 1) //判断最后一个bit为1
{
result = (result * x) % p;
}
y >>= 1; //乘除2都用位运算,效率高
x = (x * x) % p;
}
return result;
}
3. 费尔马小定理
题目如下:
设p = 23和a = 5,使用费尔马小定理计算a^{2020} mod p
因为
p
=
23
p=23
p=23是素数,由费马小定理可得
5
22
≡
1
(
m
o
d
23
)
5^{22}\equiv 1 (mod 23)
522≡1(mod23),
又因为
5
2020
=
5
91
∗
22
+
18
5^{2020} =5^{91*22+18}
52020=591∗22+18,则
5
2020
5^{2020}
52020 mod
23
=
5
18
23=5^{18}
23=518 mod
23
=
6
23=6
23=6
4. 欧拉定理
题目如下:
使用欧拉定理计算2^{100000} mod 55
55=5*11,5、11均为素数,则
Φ
(
55
)
=
(
5
−
1
)
(
11
−
1
)
=
40
\Phi(55)=(5-1)(11-1)=40
Φ(55)=(5−1)(11−1)=40
由欧拉定理可得
2
40
2 ^ {40}
240 mod 55 = 1
因此
2
100000
2^{100000}
2100000mod 55 =
2
2500
∗
40
2^{2500*40}
22500∗40mod 55 = 1
5. 手动计算7^{1000}的最后两个数位等于什么?
这里我们将题目转化为求 7 1000 7^{1000} 71000 mod 100 ,这样我们便可以用欧拉定理进行求解:
因为
100
=
5
2
×
2
2
100=5^{2}\times 2^{2}
100=52×22,
Φ
(
100
)
=
100
(
1
−
1
/
5
)
(
1
−
1
/
2
)
=
40
\Phi(100)=100(1-1/5)(1-1/2)=40
Φ(100)=100(1−1/5)(1−1/2)=40
由欧拉定理可得
7
40
7 ^ {40}
740 mod 100 = 1, 因此
7
1000
7^{1000}
71000mod 100 =
7
25
∗
40
7^{25*40}
725∗40mod 100 = 1
从而得到7^{1000}的最后两个数位等于01