请教了大佬bitset的优美用法——矩阵乘法
复杂度降低到(n^3/64约等于n^2)
以A*B=C(mod 3)的矩阵乘法为例:
方法:模拟了这样一个情况:
bitset <>a[3][i][j],a[k][i][j]表示模为矩阵a[i][j]的状态是否为k,是为1,否为0,同理bitset<>b[3][i][j]
比如A[1]={1,2,0,1},第1列B[1]={2,1,1,0}
通过bitset存储状态后,可以得到:
a[0][1][]={0,0,1,0}
a[1][1][]={1,0,0,1}
a[2][1][]={0,1,0,0}
b[0][1][]={0,0,0,1}
b[1][1][]={0,1,1,0}
b[2][1][]={1,0,0,0}
c[i][j]=1*(模数1&1)+2*(模数1&2)+2*(模数2&1)+2*2*(模数2&2)
上代码!:
#include<cstdio>
#include<math.h>
#include<string.h>
#include<vector>
#include<algorithm>
#include<queue>
#include<bitset>
#include<iostream>
#define pi pair<int,int>
#define CLR(a,b) memset(a,b,sizeof(a))
#define ll long long
using namespace std;
const int maxn=808;
bitset<maxn>a[3][maxn],b[3][maxn];
int main(){
int n;
while(~scanf("%d",&n)){
CLR(a,0);
CLR(b,0);
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
int m;
scanf("%d",&m);
if(m){
a[m%3][i][j]=1;
}
}
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
int m;
scanf("%d",&m);
if(m){
b[m%3][j][i]=1;
}
}
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
int ans=0;
ans+=(a[1][i]&b[1][j]).count();
ans+=2*((a[1][i]&b[2][j]).count ());
ans+=2*((a[2][i]&b[1][j]).count ());
ans+=(a[2][i]&b[2][j]).count ();
if(j)printf(" ");
printf("%d",ans%3);
}
printf("\n");
}
}
}