BZOJ2351: [BeiJing2011]Matrix 行列哈希
ull的读写用%llu,二维哈希跟二维前缀和是一个方法
//#include<bits/stdc++.h> //#pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<algorithm> #include<queue> #include<string.h> #include<iostream> #include<math.h> #include<stack> #include<set> #include<map> #include<vector> #include<iomanip> #include<bitset> using namespace std; // #define ll long long #define ull unsigned long long #define pb push_back #define FOR(a) for(int i=1;i<=a;i++) #define sqr(a) (a)*(a) #define dis(a,b) sqrt(sqr(a.x-b.x)+sqr(a.y-b.y)) ll qp(ll a,ll b,ll mod){ ll t=1;while(b){if(b&1)t=t*a%mod;b>>=1;a=a*a%mod;}return t; } struct DOT{ll x;ll y;}; inline void read(int &x){int k=0;char f=1;char c=getchar();for(;!isdigit(c);c=getchar())if(c=='-')f=-1;for(;isdigit(c);c=getchar())k=k*10+c-'0';x=k*f;} const int dx[4]={0,0,-1,1}; const int dy[4]={1,-1,0,0}; const int inf=0x3f3f3f3f; const ll Linf=0x3f3f3f3f3f3f3f3f; const ll mod=1e6+3; const int maxn=1e3+56; const int BASE1=137; const int BASE2=211; int m,n,a,b,q; struct NODE{ ull num; int nxt; }table[maxn*maxn+5]; ull sum[maxn][maxn],power1[maxn],power2[maxn]; int hash_table[mod],tot; void Hash(ull x){ int pos=x%mod; table[++tot].num=x; table[tot].nxt=hash_table[pos]; hash_table[pos]=tot; } bool find(ull x){ int pos=x%mod; for(int i=hash_table[pos];i;i=table[i].nxt){ if(table[i].num==x)return true; } return false; } int main(){ scanf("%d%d%d%d",&m,&n,&a,&b); for(int i=1;i<=m;i++)for(int j=1;j<=n;j++){ scanf("%1llu",&sum[i][j]); } for(int i=1;i<=m;i++)for(int j=1;j<=n;j++){ sum[i][j]+=sum[i-1][j]*BASE1; } for(int i=1;i<=m;i++)for(int j=1;j<=n;j++){ sum[i][j]+=sum[i][j-1]*BASE2; } power1[0]=power2[0]=1; for(int i=1;i<=1000;i++){ power1[i]=power1[i-1]*BASE1; power2[i]=power2[i-1]*BASE2; } for(int i=a;i<=m;i++){ for(int j=b;j<=n;j++){ ull tmp=sum[i][j] -sum[i-a][j]*power1[a] -sum[i][j-b]*power2[b] +sum[i-a][j-b]*power1[a]*power2[b]; Hash(tmp); } } for(scanf("%d",&q);q;q--){ for(int i=1;i<=a;i++)for(int j=1;j<=b;j++){ scanf("%1llu",&sum[i][j]); } for(int i=1;i<=a;i++)for(int j=1;j<=b;j++){ sum[i][j]+=sum[i-1][j]*BASE1; } for(int i=1;i<=a;i++)for(int j=1;j<=b;j++){ sum[i][j]+=sum[i][j-1]*BASE2; } ull tmp=sum[a][b]; if(find(tmp))puts("1"); else puts("0"); } }