3318 Matrix Multiplication
問題概要
n次正方行列A,B,Cが与えられる。
A×B=Cが成り立っているかを判定せよ。
n≦500,A,Bの各成分は絶対値100以下、Cの各成分の絶対値は10億以下とする。
解法
問題文中の警告にあるようにO(n^3)でやるとTLE.(どんだけテストデータ膨大なんだ)
B,Cの各行ベクトルごとにrolling hashを計算した列ベクトルをl,rとすれば、
Al=rとなっているはずなので、rolling hashの基数を2通りくらい試して、両方で答えが合っているかを見てやる。
rolling hashは文字列一致や回文判定のときによく使うハッシュで、
b0,b1,b2,...bn-1を進数と見た値である。すなわち、
b0*h^n-1 + b1*h^n-2 + …… + b1*1
ソースコード
int n,A[500][500],B[500][500],C[500][500]; int l[500],r[500]; bool ck(int w){ rep(i,n){ l[i]=r[i]=0; rep(j,n){ l[i]*=w; l[i]+=B[i][j]; r[i]*=w; r[i]+=C[i][j]; } } rep(i,n){ rep(j,n)r[i]-=A[i][j]*l[j]; if(r[i])return 0; } return 1; } int main(){ scanf("%d",&n); rep(i,n)rep(j,n)scanf("%d",A[i]+j); rep(i,n)rep(j,n)scanf("%d",B[i]+j); rep(i,n)rep(j,n)scanf("%d",C[i]+j); puts(ck(101)&&ck(103)?"YES":"NO"); return 0; }