CINTA作业二
7. 手动计算以下模
m
m
m 下
a
a
a 的乘法逆元。
(a)
m
=
11
,
a
=
5
;
m=11,a=5;
m=11,a=5;
[
1
0
11
0
1
5
]
\left[ \begin{matrix} 1&0&11\\ 0&1&5 \end{matrix} \right]
[1001115]
解:
[
0
1
5
1
−
2
1
]
(1)
\left[ \begin{matrix} 0&1&5\\ 1&-2&1 \end{matrix}\tag{1} \right]
[011−251](1)
{
r
=
1
s
=
−
2
b
=
1
(2)
\left\{ \begin{aligned} r&=&1\\ s&=&-2\\ b&=&1 \end{aligned}\tag{2} \right.
⎩
⎨
⎧rsb===1−21(2)
(b)
m
=
121
,
a
=
13
;
m=121,a=13;
m=121,a=13;
[
1
0
121
0
1
13
]
\left[ \begin{matrix} 1&0&121\\ 0&1&13 \end{matrix} \right]
[100112113]
解:
[
0
1
13
1
−
9
4
]
(1)
\left[ \begin{matrix} 0&1&13\\ 1&-9&4 \end{matrix}\tag{1} \right]
[011−9134](1)
[
1
−
9
4
−
3
28
1
]
(2)
\left[ \begin{matrix} 1&-9&4\\ -3&28&1 \end{matrix}\tag{2} \right]
[1−3−92841](2)
{
r
=
−
3
s
=
28
b
=
1
(3)
\left\{ \begin{aligned} r&=&-3\\ s&=&28\\ b&=&1 \end{aligned}\tag{3} \right.
⎩
⎨
⎧rsb===−3281(3)
©
m
=
1021
,
a
=
131
;
m=1021,a=131;
m=1021,a=131;
[
1
0
1021
0
1
131
]
\left[ \begin{matrix} 1&0&1021\\ 0&1&131 \end{matrix} \right]
[10011021131]
解:
[
0
1
131
1
−
7
104
]
(1)
\left[ \begin{matrix} 0&1&131\\ 1&-7&104 \end{matrix}\tag{1} \right]
[011−7131104](1)
[
1
−
7
104
−
1
8
27
]
(2)
\left[ \begin{matrix} 1&-7&104\\ -1&8&27 \end{matrix}\tag{2} \right]
[1−1−7810427](2)
[
−
1
8
27
4
−
31
23
]
(3)
\left[ \begin{matrix} -1&8&27\\ 4&-31&23 \end{matrix}\tag{3} \right]
[−148−312723](3)
[
4
−
31
23
−
5
39
4
]
(4)
\left[ \begin{matrix} 4&-31&23\\ -5&39&4 \end{matrix}\tag{4} \right]
[4−5−3139234](4)
[
−
5
39
4
29
−
226
3
]
(5)
\left[ \begin{matrix} -5&39&4\\ 29&-226&3 \end{matrix}\tag{5} \right]
[−52939−22643](5)
[
29
−
226
3
−
34
265
1
]
(6)
\left[ \begin{matrix} 29&-226&3\\ -34&265&1 \end{matrix}\tag{6} \right]
[29−34−22626531](6)
{
r
=
−
34
s
=
265
b
=
1
\begin{gather} \begin{cases} r=-34\\ s=265\\ b=1 \end{cases} \end{gather}
⎩
⎨
⎧r=−34s=265b=1
8. 编写C语言程序完成模指数运算,即给定整数 x , y x,y x,y 和 m m m 为输入,计算并计算返回值 x y m o d m x^y \mod m xymodm。
#include<iostream>
using namespace std;
long long int powANDmod(int x,int y,long long m){
if(y<0) y=~y+1;
long long res=1;
while(y!=0){
if(y&1) res=(res*x)%m;
x=(x*x);
res%=m; //自己想的:猜测此层面只需 res%=m;
// x=(x*x)%m; //bintou老师的解法
y=y>>1;
}
return res;
}
int main(){
int a,b;
long long c;
cout<<"Please input numbers (x,y,m): "
cin>>a>>b>>c;
long long int t=powANDmod(a,b,c);
cout<<t<<endl;
return 0;
}
9. 定义 Fibonacci 数列如下: F ( 0 ) = 0 , F ( 1 ) = 1 F(0)=0,F(1)=1 F(0)=0,F(1)=1,且对于 n ⩽ 2 , F ( n ) = F ( n − 1 ) + F ( n − 2 ) n\leqslant 2,F(n)=F(n-1)+F(n-2) n⩽2,F(n)=F(n−1)+F(n−2)。所以,该数列是: 0 , 1 , 1 , 2 , 3 , 5 , 8 , 13 , 21 , . . 0,1,1,2,3,5,8,13,21,.. 0,1,1,2,3,5,8,13,21,..。如何能快速地求出 F ( n ) F(n) F(n) 呢?很幸运,我们有以下等式:
[ 1 1 1 0 ] n = [ F ( n + 1 ) F ( n ) F ( n ) F ( n − 1 ) ] \begin{equation} \left[ \begin{matrix} 1&1\\ 1&0 \end{matrix} \right]^n= \left[ \begin{matrix} F(n+1)&F(n)\\ F(n)&F(n-1) \end{matrix} \right] \end{equation} [1110]n=[F(n+1)F(n)F(n)F(n−1)]
虽然,看上去该算法需要一次矩阵的指数运算,但是借助快速指数运算的方法,这里可以产生一个快速求解 F ( n ) F(n) F(n) 的算法。请给出算法,并编程实现,C 语言或者 Python 都可以。
#include<iostream>
using namespace std;
#define M 2
long long Fibo(int y){
while(y<1){
cerr<<"Error, this number is lower than 1."<<endl
<<"Please input n again: ";
cin>>y;
}
long long x[M][M]={{1,1},{1,0}},oth[M][M]={{1,1},{1,0}},temp[M][M];
y--; //这里多了一次偏移
while(y!=0){
if(y&1){
//res*=x; 实际上没必要的矩阵乘法:因为有限个值(4个)可以直接算
for(int i=0;i<M;i++){
for(int j =0;j<M;j++){
temp[i][j]=0;
for(int k=0;k<M;k++)
temp[i][j]+=oth[i][k]*x[k][j];
}
}
//进行oth值的更新
for(int i=0;i<M;i++){
for(int j=0;j<M;j++){
oth[i][j]=temp[i][j];
}
}
}
//x*=x;
for(int i=0;i<M;i++){
for(int j=0;j<M;j++){
temp[i][j]=0;
for(int k=0;k<M;k++){
temp[i][j]+=x[i][k]*x[k][j];
}
}
}
//进行x值的更新
for(int i=0;i<M;i++){
for(int j=0;j<M;j++){
x[i][j]=temp[i][j];
}
}
y=y>>1;
}
return oth[1][0];
}
int main(){
for(int i=1;i<50;i++) cout<<Fibo(i)<<endl;
return 0;
}
10. 给定互素的正整数 c c c 和 m m m,请证明在 m o d mod mod m m m 的意义上存在唯一确定的整数值 c − 1 c^{-1} c−1,它使得 c c − 1 ≡ 1 cc^{-1}\equiv 1 cc−1≡1
存在性证明:
对于互素的两数:
g
c
d
(
c
,
m
)
=
1
gcd(c,m)=1
gcd(c,m)=1
那么我们由扩展欧几里得算法必定可以得到:
c
r
+
m
s
=
1
cr+ms=1
cr+ms=1
而这代表着
x
r
+
m
s
=
1
xr+ms=1
xr+ms=1 必定成立(无论
c
c
c 与
c
−
1
c^{-1}
c−1 是否相等)
设
1
≤
c
−
1
<
m
1\leq c^{-1}<m
1≤c−1<m 证明其唯一性:
假设存在另一数
c
1
c_1
c1
c
c
−
1
≡
c
c
1
≡
1
(
m
o
d
m
)
cc^{-1}\equiv cc_1\equiv 1(\mod m)
cc−1≡cc1≡1(modm)
那么:
m
∣
(
c
−
1
−
c
1
)
m|(c^{-1}-c_1)
m∣(c−1−c1)
所以在规定区间,仅有一个值
编程题:编写一个 Python 程序计算乘法逆元,即输入互素的正整数 c c c 和 m m m,返回 c c c ,使得 c c − 1 ≡ ( m o d m ) cc^{−1} ≡ (\mod m) cc−1≡(modm)。要求:只返回为正整数的 c − 1 c^{−1} c−1。
# 乘法逆元算法,要求带有c,m
def egcd(c, m):
r0, s0 = 1, 0
r1, s1 = 0, 1
while m % c != 0:
q = m // c
c, m = m % c, c
r0, r1 = r1, r0 - q * r1
s0, s1 = s1, s0 - q * s1
# return r1, s1, c
if s1 <= 0:
return s1 + m
return s1
c = eval(input("c: "))
m = eval(input("m: "))
# li = list(egcd(c, m))
# print("The result:\n\t\t r={}, s={}, b={}".format(li[-3], li[-2], li[-1]))
print("The result is: ", egcd(c, m))