您的位置:首页 > 其它

hdu 4965 Fast Matrix Calculation 快速矩阵幂

2014-08-20 17:27 483 查看
【题意】一个矩阵N*K的矩阵A,一个K*N的矩阵B,(4 <= N <= 1000,2 <=K <= 6)。先进行矩阵乘法C=A*B,然后进行D=C^(N*N)的幂运算,然后

对D的每个数对6取模,最后求出D的所有位置数字之和。

【解法】 直接按照题目上的做 A*B 形成一个N*N的矩阵C,再用C求其n*n次幂。这样果断超时啊。

看了题解(AB)^n 可以写成 A (BA)^(n-1) B , B*A 形成的矩阵就是K*K的,这里果断省了一大把时间啊,这么简单的变换为毛我们就是没想到泪奔

【注意】平时都是用结构体进行快速幂运算,但是要是结构体里的数组太大了就会ce。这里我只有一部分是用的结构体,后一部分用的数组。

#include<iostream>
#include<cstdio>
#include<map>
#include<algorithm>
#include<cstring>
#define INF 9999999
using namespace std;
struct node
{
int mat[7][7];
} no;

int a[1002][7],b[7][1002],cc[1002][1002],aa[1002][7];

node mul(node a,node b,int n,int m,int p)
{
node c;
memset(c.mat,0,sizeof(c.mat));
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
if(a.mat[i][j])
{
for(int k=0; k<p; k++)
c.mat[i][k]=(c.mat[i][k]+a.mat[i][j]*b.mat[j][k])%6;
}
return c;
}

node solve(node a,int num,int n)
{
node b;
memset(b.mat,0,sizeof(b.mat));
for(int i=0; i<n; i++)
b.mat[i][i]=1;
while(num)
{
if(num%2)
b=mul(b,a,n,n,n);
a=mul(a,a,n,n,n);
num/=2;
}
return b;
}

int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
if(n==0&&m==0)
break;
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
scanf("%d",&a[i][j]);

for(int i=0; i<m; i++)
for(int j=0; j<n; j++)
scanf("%d",&b[i][j]);

memset(no.mat,0,sizeof(no.mat));
for(int i=0; i<m; i++)
for(int j=0; j<n; j++)
if(b[i][j])
{
for(int k=0; k<m; k++)
no.mat[i][k]=(no.mat[i][k]+b[i][j]*a[j][k])%6;
}

no=solve(no,n*n-1,m);

memset(aa,0,sizeof(aa));
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
if(a[i][j])
{
for(int k=0; k<m; k++)
aa[i][k]=(aa[i][k]+a[i][j]*no.mat[j][k])%6;
}

memset(cc,0,sizeof(cc));
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
if(aa[i][j])
{
for(int k=0; k<n; k++)
cc[i][k]=(cc[i][k]+aa[i][j]*b[j][k])%6;
}
int ans=0;
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
ans+=cc[i][j];
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: