【题解】 bzoj2462: [BeiJing2011]矩阵模板

题面戳我

Solution

  • 二维矩阵\(hash\),判断即可
  • 自己YY了一个方法,\(bzoj\)T到飞,(一开始还用的三\(hash\)),交到luogu貌似跑的不慢啊qwq
  • (我是不会告诉你全输出1即可AC)

Update

  • 我这个代码复杂度是错的\(O(n^4)\)的(我就说怎么卡不进时间,跑的还没暴力快)
  • 正确做法应该是预处理出所有的子矩阵的\(Hash\)值,然后判重即可,这样就是\(O(n^2)\)的了

Code

  • 伪·二维\(hash\)
// luogu-judger-enable-o2
//It is coded by ning_mew on 7.24
#include<bits/stdc++.h>
#define LL long long
#define US unsigned
using namespace std;

const int maxn=1007;

int n,m,A,B,Q=0;
char ch[maxn][maxn],q[maxn][maxn];
LL MOD[3]={19260817,20000909,19491001};
LL Hash[3][maxn][maxn],Pow[3][maxn];
LL box[3][maxn];

inline void pre(){
    for(US int k=0;k<1;k++){
        Pow[k][0]=1;
        for(US int i=1;i<=n;i++){
            Hash[k][i][0]=0;
            for(US int j=1;j<=m;j++){
                Hash[k][i][j]=(Hash[k][i][j-1]*2+(ch[i][j]-'0'))%MOD[k];
                Pow[k][j]=(2*Pow[k][j-1])%MOD[k];
            }
            //cout<<ch[i]+1<<endl;
            //cout<<" pre_hash:"<<k<<' '<<i<<' '<<' '<<Hash[k][i][m]<<endl;
        }
    }
}
inline bool check(int x,int y){
    for(US int k=0;k<1;k++){
        for(US int i=x;i<=x+A-1;i++){
            LL sa=((Hash[k][i][y+B-1]-Hash[k][i][y-1]*Pow[k][B])%MOD[k]+MOD[k])%MOD[k];
            LL sb=box[k][i-x+1];
            if(sa!=sb)return false;
        }
    }return true;
}
inline void work(){
    //memset(box,0,sizeof(box));
    for(US int k=0;k<1;k++){
        for(US int i=1;i<=A;i++){
            box[k][i]=0;
            for(US int j=1;j<=B;j++){
                box[k][i]=(box[k][i]*2+(q[i][j]-'0'))%MOD[k];
            }//cout<<" q_hash:"<<k<<' '<<i<<' '<<box[k][i]<<endl;
        }
    }
    for(US int x=1;x<=n-A+1;x++){
        for(US int y=1;y<=m-B+1;y++){
            if(check(x,y)){printf("1\n");return;}
        }
    }printf("0\n");return;
}
int main(){
    scanf("%d%d%d%d",&n,&m,&A,&B);
    for(US int i=1;i<=n;i++)scanf("%s",ch[i]+1);//,cout<<ch[i]+1<<endl;//cin>>ch[i]+1;
    pre(); scanf("%d",&Q);
    for(US int i=1;i<=Q;i++){
        for(US int j=1;j<=A;j++)scanf("%s",q[j]+1);//,cout<<q[j]+1<<endl;//cin>>q[j]+1;
        work();
    }return 0;	
}

博主蒟蒻,随意转载。但必须附上原文链接:http://www.cnblogs.com/Ning-Mew/,否则你会场场比赛爆0!!!

posted @ 2018-08-25 19:31  Ning_Mew  阅读(303)  评论(0编辑  收藏  举报