首页 > 学院 > 开发设计 > 正文

[BZOJ1567][JSOI2008]Blue Mary的战役地图(二分+hash)

2019-11-08 01:33:38
字体:
来源:转载
供稿:网友

题目描述

传送门

题解

二分答案之后O(n2)矩阵hash 就是个裸题

代码

#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<cmath>#include<map>using namespace std;#define UL unsigned long long#define N 55const UL s=23333333333LL;const UL S=3115439631056497LL;int n,ans,a[N][N],b[N][N];UL mis[N],miS[N],c[N][N],d[N][N];map <UL,bool> hash;bool check(int mid){ for (int i=1;i<=n;++i) { c[i][1]=(UL)a[i][1]; for (int j=2;j<=mid;++j) c[i][1]=c[i][1]*s+(UL)a[i][j]; for (int j=2;j<=n-mid+1;++j) c[i][j]=(c[i][j-1]-(UL)a[i][j-1]*mis[mid-1])*s+(UL)a[i][j+mid-1]; } for (int i=1;i<=n-mid+1;++i) { d[1][i]=c[1][i]; for (int j=2;j<=mid;++j) d[1][i]=d[1][i]*S+c[j][i]; for (int j=2;j<=n-mid+1;++j) d[j][i]=(d[j-1][i]-c[j-1][i]*miS[mid-1])*S+c[j+mid-1][i]; } hash.clear(); for (int i=1;i<=n-mid+1;++i) for (int j=1;j<=n-mid+1;++j) hash[d[i][j]]=1; for (int i=1;i<=n;++i) { c[i][1]=(UL)b[i][1]; for (int j=2;j<=mid;++j) c[i][1]=c[i][1]*s+(UL)b[i][j]; for (int j=2;j<=n-mid+1;++j) c[i][j]=(c[i][j-1]-(UL)b[i][j-1]*mis[mid-1])*s+(UL)b[i][j+mid-1]; } for (int i=1;i<=n-mid+1;++i) { d[1][i]=c[1][i]; for (int j=2;j<=mid;++j) d[1][i]=d[1][i]*S+c[j][i]; for (int j=2;j<=n-mid+1;++j) d[j][i]=(d[j-1][i]-c[j-1][i]*miS[mid-1])*S+c[j+mid-1][i]; } for (int i=1;i<=n-mid+1;++i) for (int j=1;j<=n-mid+1;++j) if (hash[d[i][j]]) return 1; return 0;}int find(){ int l=1,r=n,mid,ans=0; while (l<=r) { mid=(l+r)>>1; if (check(mid)) ans=mid,l=mid+1; else r=mid-1; } return ans;}int main(){ scanf("%d",&n); mis[0]=1LL;for (int i=1;i<=n;++i) mis[i]=mis[i-1]*s; miS[0]=1LL;for (int i=1;i<=n;++i) miS[i]=miS[i-1]*S; for (int i=1;i<=n;++i) for (int j=1;j<=n;++j) scanf("%d",&a[i][j]); for (int i=1;i<=n;++i) for (int j=1;j<=n;++j) scanf("%d",&b[i][j]); ans=find(); PRintf("%d/n",ans);}
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表