算法训练 矩阵乘方主题:
问题的说明
给出矩阵a,给出非负整数b和正整数m,求出a的b次方除以m后的馀数。
一个nxn的矩阵除以m的馀数仍然是nxn的矩阵,这个矩阵的各元素除以原矩阵对应位置的m的馀数。
为了计算这个问题,可以将a进行b次相乘,每次对m求馀数,但是这个方法特别慢,b大的时候不能使用。 展示了以下快速算法。 用A^b表示a的b次方。
如果b=0,则A^b%m=I%m。 这里,I表示单位矩阵。
如果b是偶数,则a^b%m=(a^(b/2 ) m )2%m ),即首先将a乘以b /平方,对m求余数,然后平方,对m求余数。
如果b为奇数,则a^b%m=(a^(b-1) m ) a%m ),即首先将a乘以b-1次幂,对m求馀数,然后乘a对m求馀数。
此方法速度很快,请用此方法计算A^b%m。 其中,a是2x2的矩阵,m为10000以下。
输入格式
输入第一行包含两个整数b、m,第二行和第三行中的每行包含两个整数,即矩阵a。
输出格式
输出有两行,每行有两个整数,表示A^b%m的值。
样品输入
2 2
1 1
0 1
样品输出
1 0
0 1
分析:从问题中可以得到一组等式。 b=0时,A^b%m=I%m; 如果b=奇数,则a^b%m=(a^(b/2 ) m ) )如果mb=偶数,则a^b%m=(a^(b-1) %m ) ) m )2) m得到递归公式。 如果b=0,则f(0) )。 当b=奇数时,f(b )=f ) b/2 ) ) mb=偶数时,f ) b )=f(B-1 ) ) m
代码其中# include stdio.h # include math.h # definesize2typedefstructmatrix { int map [ size ]; }Matrix; matrixi={ 1,0,0,1 }; 矩阵p; int b,m; matrixmul_m(matrixa,Matrix b )//运算) a乘以a次,对m求余数) int i,j,k; 矩阵密度; for(I=0; i SIZE; I ) for ) j=0; j SIZE; j({re.map[I][j]=0; for(k=0; k SIZE; k ) re.map [ I ] [ j ]=a.map [ I ] [ k ] * b.map [ k ] [ j ]; re.map[i][j] %=m; } return re; } Matrix fun () {Matrix temp=p,re=I; for (; (if ) b=0)空白; if(B1==1) (/奇数re=mul_m ) re,temp ); b --; }temp=mul_m(temp,temp ); //偶数b=b1; }return re; (}int main ) ) {int i,j; scanf('%d%d )、b、m ); scanf('%d%d )、p.map[0][0]、p.map[0][1]; scanf () %d%d )、p.map[1][0]、p.map[1][1]; 矩阵密度; if(b==0) )//处理b为0时,b=0为fun ) )中for ) I=0; i SIZE; I ) for ) j=0; j SIZE; j({re.map[I][j]=I.map[I][j]%m; }} else {re=fun (; (for ) I=0; i SIZE; I ) for(j=0; j SIZE; j ) printf('%d ',re.map[i][j]; 打印((n ); }return 0; }