HDU4965 Fast Matrix Calculation【矩阵快速幂】

来源:互联网 发布:红色网络家园 编辑:程序博客网 时间:2024/05/21 07:00

题意:C = A * B, M = C ^ (n*n),求M中元素MOD 6以后的SUM


思路:A*B最大1000*1000,快速幂要炸,我们转换一下

比如(A*B)^4 = ABABABAB = A(BA)(BA)(BA)B = A*(BA)^3*B

B*A最大6*6 这样就快了


为什么我结构体里开数组s[1005][1005],程序一运行就停,照理说这也不大啊,不清楚怎么回事,谁知道告诉我一声,谢谢!


#include<stdio.h>#include<iostream>#include<string.h>#include<string>#include<stdlib.h>#include<math.h>#include<vector>#include<list>#include<map>#include<stack>#include<queue>#include<algorithm>#include<numeric>#include<functional>using namespace std;typedef long long ll;const int maxn = 1005;int MOD,N;int a[maxn][10],b[10][maxn];int aa[maxn][10],ss[maxn][maxn];struct data{int s[10][10];}res,tp;void init(){memset(res.s,0,sizeof res.s);memset(tp.s,0,sizeof tp.s);for(int i = 1; i <= N; i++)res.s[i][i] = 1;}struct data mat(struct data &x,struct data &y){struct data temp;memset(temp.s,0,sizeof temp.s);for(int i = 1; i <= N; i++){for(int j = 1; j <= N; j++){for(int k = 1; k <= N; k++){temp.s[i][j] += x.s[i][k] * y.s[k][j];temp.s[i][j] %= MOD;}}}return temp;}int main(void){int n,m;MOD = 6;while(scanf("%d%d",&n,&m)!=EOF && n+m){for(int i = 1; i <= n; i++){for(int j = 1; j <= m; j++)scanf("%d",&a[i][j]);}for(int i = 1; i <= m; i++){for(int j = 1; j <= n; j++)scanf("%d",&b[i][j]);}N = m;init();for(int i = 1; i <= m; i++){for(int j = 1; j <= m; j++){for(int k = 1; k <= n; k++){tp.s[i][j] += b[i][k] * a[k][j];tp.s[i][j] %= MOD;}}}int bb = n*n-1;while(bb){if(bb&1)res = mat(res,tp);bb >>= 1;tp = mat(tp,tp);}memset(aa,0,sizeof aa);for(int i = 1; i <= n; i++){for(int j = 1; j <= m; j++){for(int k = 1; k <= m; k++){aa[i][j] += a[i][k] * res.s[k][j];aa[i][j] %= MOD;}}}memset(ss,0,sizeof ss);for(int i = 1; i <= n; i++){for(int j = 1; j <= n; j++){for(int k = 1; k <= m; k++){ss[i][j] += aa[i][k] * b[k][j];ss[i][j] %= MOD;}}}ll ans = 0;for(int i = 1; i <= n; i++){for(int j = 1; j <= n; j++)ans += ss[i][j];}printf("%lld\n",ans);}return 0;}


阅读全文
0 0