递归与分治——矩阵快速幂

递归与分治——矩阵快速幂

问题

对一个t阶方阵,要求计算A的n次mod p,其中n是一个很大的数。mod p表示矩阵的每个元素对p取模。

输入

t(矩阵的阶,<=100),n,p,A(非负矩阵,按行,空隔输入)

输出

A的n次 mod p,mod p指对A的每个元素对p取模,分行空隔输出,再输出运行时间。

递归与分治——矩阵快速幂_第1张图片

实验方法:

快速幂算法

完整代码

#include
#include
#include
#include
using namespace std;
#define ll long long
const int MAXN=101;
ll n,k,mod,a[MAXN][MAXN],b[MAXN][MAXN],ans[MAXN][MAXN],c[MAXN][MAXN];
 void ksm(int n,int m,int mod)
 {
     while(m>1)
     {
         memset(b,0,sizeof(b));
         if(m%2==1)
         {
             for(int i=1;i<=n;i++)
                 for(int j=1;j<=n;j++)
                 {
                     for(int k=1;k<=n;k++)
                     c[i][j]=(c[i][j]+ans[i][k]*a[k][j]%mod)%mod;
                 }
             for(int i=1;i<=n;i++)
                 for(int j=1;j<=n;j++){
                 	ans[i][j]=c[i][j];
				    c[i][j]=0;
				 }
         }
         for(int i=1;i<=n;i++)
             for(int j=1;j<=n;j++)
                 for(int k=1;k<=n;k++)
                	 b[i][j]=(b[i][j]+a[i][k]*a[k][j]%mod)%mod;
         for(int i=1;i<=n;i++)
             for(int j=1;j<=n;j++)
             	a[i][j]=b[i][j];
         m=m/2;
     }
    for(int i=1;i<=n;i++)
         for(int j=1;j<=n;j++)
         {
            for(int k=1;k<=n;k++)
            	c[i][j]=(c[i][j]+ans[i][k]*a[k][j]%mod)%mod;
         }
     for(int i=1;i<=n;i++)
         for(int j=1;j<=n;j++){
         	ans[i][j]=c[i][j];
			c[i][j]=0;
		 }
 }
int main(){
	clock_t start,finish;
	double duration;
    scanf("%lld%lld%lld",&n,&k,&mod);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++) 
			scanf("%lld",&a[i][j]);
    start=clock();
	for(int i=1;i<=n;i++)
     	ans[i][i]=1;
    ksm(n,k,mod);
    finish=clock();
    duration=(double)(finish-start)/CLOCKS_PER_SEC;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        if(j!=n)
        	printf("%lld ",ans[i][j]%mod);
        else
			printf("%lld\n",ans[i][j]%mod);
    }
    printf("%lf\n",duration);
    return 0;
 }

你可能感兴趣的:(递归与分治)