您的位置:首页 > 其它

hdu4965---Fast Matrix Calculation (矩阵交结合律)(快速幂)

2016-07-26 13:58 344 查看
这道题要用到一个矩阵结合律的知识点,很巧妙,但是不了解矩阵性质就很难想到。

还有结构体内部的数组不能太大,否则会爆栈!

即 A*B*A*B*A*B*A*B......A*B 可以转化为A*(B*A*B*A*B*A*B......A)*B ,也就是ans = B*A*B*A*B*A..,最后A*ans*B就行了

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;

const int maxn = 1005;
int N,K;
int A[maxn][maxn],B[maxn][maxn],tmp1[maxn][maxn],tmp2[maxn][maxn];

struct matrix {
int m[20][20];
matrix() {
memset(m,0,sizeof(m));
}
};

matrix mul(matrix a,matrix b) {
matrix tmp;
for(int i = 1;i <= K;i++)
for(int j = 1;j <= K;j++)
for(int k = 1;k <= K;k++)
tmp.m[i][j] = (tmp.m[i][j] + a.m[i][k] * b.m[k][j]) % 6;
return tmp;
}

matrix powmul(matrix a,int x) {
matrix tmp;
for(int i = 1;i <= K;i++)
tmp.m[i][i] = 1;
while(x) {
if(x & 1)
tmp = mul(tmp,a); //别忘了前面的$tmp = $部分
a = mul(a,a);
x >>= 1;
}
return tmp;
}

int main() {
while(scanf("%d%d",&N,&K) != EOF && N && K) {
matrix ans;
memset(A,0,sizeof(A));
memset(B,0,sizeof(B));
memset(tmp1,0,sizeof(tmp1));
memset(tmp2,0,sizeof(tmp2));
for(int i = 1;i <= N;i++)
for(int j = 1;j <= K;j++)
scanf("%d",&A[i][j]);
for(int i = 1;i <= K;i++)
for(int j = 1;j <= N;j++)
scanf("%d",&B[i][j]);
for(int i = 1;i <= K;i++)
for(int j = 1;j <= K;j++)
for(int k = 1;k <= N;k++)
ans.m[i][j] = (ans.m[i][j] + B[i][k] * A[k][j]) % 6;
ans = powmul(ans,(N*N)-1);
//pi(ans,K);
for(int i = 1;i <= N;i++)
for(int j = 1;j <= K;j++)
for(int k = 1;k <= K;k++)
tmp1[i][j] = (tmp1[i][j] + A[i][k] * ans.m[k][j]) % 6;
for(int i = 1;i <= N;i++)
for(int j = 1;j <= N;j++)
for(int k = 1;k <= K;k++)
tmp2[i][j] = (tmp2[i][j] + tmp1[i][k] * B[k][j]) % 6;
int sum = 0;
//pi(tmp2,N);
for(int i = 1;i <= N;i++)
for(int j = 1;j <= N;j++)
sum += tmp2[i][j];
printf("%d\n",sum);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息