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;
}
还有结构体内部的数组不能太大,否则会爆栈!
即 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;
}
相关文章推荐
- HDU3658 How many words 矩阵快速幂
- HDU1575 Tr A
- 矩阵快速幂
- HDU 1005 Number Sequence
- hdu1757 矩阵快速幂--
- HDU 4979 A simple math problem.
- HDU 1575 Tr A
- HDU 2604 Queuing
- poj_3070 Fibonacci
- HDU2604 Queuing(矩阵快速幂模板)
- hdu 5667 Sequence【费马小定理+矩阵快速幂】
- LightOj 1006(矩阵快速幂)
- ACM_HDUOJ_2604_Queuing排队问题
- 矩阵快速幂求斐波那契数列 poj3070
- poj 3070 矩阵快速幂求斐波拉契数列
- hihocoder骨牌覆盖问题·三
- poj 2778 DNA Sequence
- HDU 5318 The Goddess Of The Moon
- UVA 10689 Yet another Number Sequence(矩阵快速幂求Fib数列)
- 矩阵的运算 --- 倍增法(UVA11149 - Power of Matrix)