CINTA作业三 同余、模指数、费尔马小定理、欧拉定理
1、实现求乘法逆元的函数,给定a和m,求a模m的乘法逆元,无解时请给出无解提示,并且只返回正整数。进而给出求解同余方程(ax = b mod m)的函数,即给定a,b,m,输出满足方程的x,无解给出无解提示。
#include <iostream>
using namespace std;
int* Egcd(int a, int b)
{
int r_0 = 1, s_0 = 0, r_1 = 0, s_1 = 1, q, temp;
if (a < b)
{
int temp = a;
a = b;
b = temp;
}
while (b)
{
q = a / b;
temp = a % b;
a = b;
b = temp;
temp = r_0 - q * r_1;
r_0 = r_1;
r_1 = temp;
temp = s_0 - q * s_1;
s_0 = s_1;
s_1 = temp;
}
int n[3];
n[0] = r_0;
n[1] = s_0;
n[2] = a;
return n;
}
//求乘法逆元
int inverse(int a, int m)
{
int* egcd = Egcd(a, m);//接收egcd算法返回的r,s,d
if (egcd[2] != 1)return 0;
return egcd[0];
}
//求解同余方程
int fun(int a, int b, int m)
{
int num = inverse(a, m);//求a模m的乘法逆元
return num * b;
}
int main()
{
int a, b, m;
cin >> a >> b >> m;
int result = fun(a, b, m);
if (result)
cout << "x mod " << m << " = " << result << " mod " << m << endl;
else
cout << "无解" << endl;
return 0;
}
2、实现模指数运算的函数,给定x、y和m,求x的y次方模m。
int ModExp(int x, int y, int m)
{
int temp = x % m, res = 1;
while (y > 0)
{
if (y % 2 == 1)
{
res *= temp;
cout << "res = " << res << endl;
}
temp *= temp;
temp %= m;
y >>= 1;
}
return res % m;
}
3、设p = 23和a = 5,使用费尔马小定理计算 a 2020 m o d p a^{2020}\ mod\ p a2020 mod p?
a 22 ≡ 1 m o d 23 a ^ {22}\ ≡\ 1\ mod\ 23 a22 ≡ 1 mod 23
原式:
KaTeX parse error: No such environment: split at position 8: \begin{̲s̲p̲l̲i̲t̲}̲ a ^ {2020}\ mo…
4、使用欧拉定理计算 2 100000 m o d 55 2^{100000}\ mod\ 55 2100000 mod 55。
ϕ ( 55 ) = 40 ϕ(55)=40 ϕ(55)=40
由于 g c d ( 2 , 55 ) = 1 gcd(2, 55)\ =\ 1 gcd(2,55) = 1 ,所以由欧拉定理可得 2 ϕ ( 55 ) ≡ 1 m o d 55 2 ^ {ϕ(55)}\ ≡\ 1\ mod\ 55 2ϕ(55) ≡ 1 mod 55
原式:
KaTeX parse error: No such environment: split at position 8: \begin{̲s̲p̲l̲i̲t̲}̲ 2 ^ {100000}\ …
5、手动计算 7 1000 7^{1000} 71000的最后两个数位等于什么?
只看后两位数可以得到以下规律:
$$
7 ^ {1} = 07\
7 ^ {2} = 49\
7 ^ {3} = 43\
7 ^ {4} = 01\
7 ^ {5} = 07\
由
此
观
之
,
四
次
一
循
环
由此观之,四次一循环
由此观之,四次一循环1000\ /\ 4\ =\ 25$$
所以 7 1000 7 ^ {1000} 71000 的后两位数分别是0, 1