HDU 4965 Fast Matrix Calculation
题意:
给你一个n*k的矩阵A,给你一个k*n的矩阵B,C = A*B, 求C^(n*n) 对6取模, 计算结果的元素和?
思路:
如果直接按照它说的做的话,会在矩阵快速幂种产生一个n*n*n的复杂度。 会t。
转换一下:
C^(n*n) = (A*B)^(n*n) = A * (B*A)^(n*(n-1)) * B,
B*A是一个6*6的,这样就可以快速幂了。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn = 1000 + 7;
const int mod = 6;
struct Mar{
int n,m;
vector<int> a[maxn];
void init(){
for (int i = 0; i < maxn ;++i) a[i].clear();
}
void read(int n,int k){
this->n = n;
this->m = k;
int x;
for (int i = 0; i < n; ++i){
for (int j = 0; j < k; ++j){
scanf("%d",&x);
a[i].push_back(x);
// scanf("%d",&a[i][j]);
}
}
}
Mar mul(Mar o){
Mar ans;
ans.init();
ans.n = n; ans.m = o.m;
for (int i = 0; i < n; ++i){
for (int j = 0; j < o.m; ++j){
int sum = 0;
for (int k = 0; k < m; ++k){
sum = (sum + a[i][k]*o.a[k][j]) % mod;
}
ans.a[i].push_back(sum);
}
}
return ans;
}
}A,B;
int n,k;
Mar my_pow(Mar a,int b){
Mar ans;
// ans.init();
for (int i = 0; i < k; ++i){
ans.a[i].resize(7);
}
for (int i = 0; i < k; ++i){
for (int j = 0; j < k; ++j){
if (i == j) ans.a[i][j] = 1;
else ans.a[i][j] = 0;
}
}
ans.n = k; ans.m = k;
while(b){
if (b & 1)
ans = ans.mul(a);
a = a.mul(a);
b >>= 1;
}
return ans;
}
int main(){
while(~scanf("%d %d",&n, &k) && (n || k)){
A.init();
B.init();
A.read(n,k);
B.read(k,n);
// puts("haha");
Mar c = B.mul(A);
c = my_pow(c,n*n-1);
A = A.mul(c);
A = A.mul(B);
int ans=0;
for (int i = 0; i < A.n; ++i){
for (int j = 0; j < A.m; ++j){
ans += A.a[i][j];
}
}
printf("%d\n",ans);
}
return 0;
}