NC13610 矩阵(二分+二维哈希)

学到了一手二维哈希,以前只会一维度,就是通过类似前缀和的思想来做

#include<bits/stdc++.h>
#define ull unsigned long long
using namespace std;
typedef long long ll;
const int N=555;
const int mod=1e9+7;
ull base1=131,base2=13131;
ull hash1[N][N],hash2[N][N];
ull p1[N],p2[N];
int n,m;
char s[N][N];
map<ull,int> m1;
void init(){
    int i;
    p1[0]=1,p2[0]=1;
    for(i=1;i<555;i++){
        p1[i]=p1[i-1]*base1;
        p2[i]=p2[i-1]*base2;
    }
     for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            hash1[i][j]=hash1[i][j-1]*base1+s[i][j]-'a';
            hash2[i][j]=hash2[i-1][j]*base2+hash1[i][j];
        }
    }
}
ull cal(int i,int j,int x){
    ull tmp=hash2[i+x-1][j+x-1];
    tmp-=hash2[i+x-1][j-1]*p1[x];
    tmp-=hash2[i-1][j+x-1]*p2[x];
    tmp+=hash2[i-1][j-1]*p1[x]*p2[x];
    return tmp;
}
bool check(int x){
    int i,j;
    m1.clear();
    for(i=1;i+x-1<=n;i++){
        for(j=1;j+x-1<=m;j++){
            ull tmp=cal(i,j,x);
            if(m1[tmp])
                return true;
            else
                m1[tmp]++;
        }
    }
    return false;
}
int main(){
    cin>>n>>m;
    int i,j;
    for(i=1;i<=n;i++){
        scanf("%s",s[i]+1);
    }
    init();
    int l=1,r=min(n,m);
    while(l<r){
        int mid=l+r+1>>1;
        if(check(mid))
            l=mid;
        else
            r=mid-1;
    }
    cout<<l<<endl;
}
View Code

 

posted @ 2020-03-30 17:10  朝暮不思  阅读(135)  评论(0编辑  收藏  举报