题意: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;
}