Live2d Test Env

Gym - 101341I:Matrix God(随机算法)

题意:给出N,以及三个矩阵A,B,C,大小都为N*N。问是否满足A*B=C; N<1000;

思路:由于矩阵乘法的复杂度为O(N^3);而部分验证又不能保证结果正确。我们巧妙地利用矩阵乘法的结合律:使其变为1*N和N*N的矩阵乘法,使复杂度降低为O(N^2); 即随机构造矩阵X(1*N),Y(N*1),那么问题成为验证X*A*B*Y==X*C*Y?然后利用结合律即可验证。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1010;
const int Mod=1e9+7;
int a[maxn][maxn],b[maxn][maxn],c[maxn][maxn];
int r1[maxn],r2[maxn],x1[maxn],x2[maxn],yy1[maxn],ans1,ans2;
int main()
{
    int T=10,N,i,j;
    scanf("%d",&N);
    for(i=1;i<=N;i++) for(j=1;j<=N;j++) scanf("%d",&a[i][j]);
    for(i=1;i<=N;i++) for(j=1;j<=N;j++) scanf("%d",&b[i][j]);
    for(i=1;i<=N;i++) for(j=1;j<=N;j++) scanf("%d",&c[i][j]);
    while(T--){
        for(i=1;i<=N;i++) r1[i]=rand()%Mod; //1*N 
        for(i=1;i<=N;i++) r2[i]=rand()%Mod; //N*1 
        for(i=1;i<=N;i++) x1[i]=x2[i]=yy1[i]=0;
        ans1=ans2=0;
        for(i=1;i<=N;i++)     //1*N  N*N N*N N*1=(1*N)*(N*1)
         for(j=1;j<=N;j++)
          (x1[i]+=(ll)r1[j]*a[j][i]%Mod)%=Mod;
        for(i=1;i<=N;i++)
         for(j=1;j<=N;j++)
          (x2[i]+=(ll)b[i][j]*r2[j]%Mod)%=Mod;
        for(i=1;i<=N;i++) (ans1+=(ll)x1[i]*x2[i]%Mod)%=Mod;
        
        for(i=1;i<=N;i++)    //1*N N*N N*1 =(1*N)*(N*1)
         for(j=1;j<=N;j++)
          (yy1[i]+=(ll)r1[j]*c[j][i]%Mod)%=Mod;
        for(i=1;i<=N;i++) (ans2+=(ll)yy1[i]*r2[i]%Mod)%=Mod;
        if(ans1!=ans2){ puts("NO"); return 0; }
    }
    puts("YES"); return 0;
}

 

posted @ 2018-06-25 21:18  nimphy  阅读(322)  评论(0编辑  收藏  举报