BZOJ 2462 矩阵模板 发表于 2017-01-15 | 更新于 2018-06-18 LinkSolution枚举每个小矩阵,依次把每行加入Trie,建立AC自动机。 用大矩阵的每一行去匹配小矩阵,如果匹配成功了,就可以计算出相应矩阵左上角的座标。 Code123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126//Code by Lucida#include<bits/stdc++.h>#define get(x) scanf("%d",&x)//#define debug(x) std::cout<<#x<<'='<<x<<std::endltemplate <class T> inline bool chkmx(T &a,const T &b){return a<b?a=b,1:0;}template <class T> inline bool chkmn(T &a,const T &b){return a>b?a=b,1:0;}const int MAXN=1000+10;using std::vector;namespace AC{ const int SIZE=MAXN*MAXN; struct Node { Node *son[2],*fail,*last; vector<int> match; Node *&next(char c){return son[c-'0'];} }*root,POOL[SIZE],*ME=POOL;//[MAXN]; Node *newNode() { static Node *cur; cur=ME++;cur->match.clear();cur->son[0]=cur->son[1]=cur->fail=cur->last=0; return cur; } void Insert(char *s,int l) { if(!root) root=newNode(); Node *cur=root; for(int i=1,L=strlen(s+1);i<=L;i++) { if(!cur->next(s[i])) cur->next(s[i])=newNode(); cur=cur->next(s[i]); } cur->match.push_back(l); } void Build() { static Node *Q[SIZE]; static int hd,ta; hd=1,ta=0; for(char c='0';c<='1';++c) { Node *&son=root->next(c); if(!son) son=root; else { son->fail=root; son->last=0; Q[++ta]=son; } } while(hd<=ta) { Node *cur=Q[hd++]; for(char c='0';c<='1';c++) { Node *&son=cur->next(c); if(!son) son=cur->fail->next(c); else { son->fail=cur->fail->next(c); son->last=son->fail->match.size()?son->fail:son->fail->last; Q[++ta]=son; } } } }}using namespace AC;int A[MAXN][MAXN],a,b;void Clear(){ ME=POOL; root=0; memset(A,0,sizeof(A));}void DFS(Node *pos,int x,int y){ for(int i=0;i<pos->match.size();i++) { int u=pos->match[i]; if(x-u+1>=1 && y-b+1>=1) A[x-u+1][y-b+1]++; } if(pos->last) DFS(pos->last,x,y);}int main(){ static char mtrx[MAXN][MAXN],str[MAXN]; int n,m;get(n),get(m),get(a),get(b); for(int i=1;i<=n;i++) scanf("%s",mtrx[i]+1); int Q;get(Q); while(Q--) { Clear(); for(int i=1;i<=a;i++) { scanf("%s",str+1); Insert(str,i); } Build(); for(int i=1;i<=n;i++) { Node *cur=root; for(int j=1;j<=m;j++) { cur=cur->next(mtrx[i][j]); if(cur->match.size()) DFS(cur,i,j); else if(cur->last) DFS(cur->last,i,j); } } int matched=0; for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) if(A[i][j]>=a) { matched=1; break; } printf("%d\n",matched); } return 0;}/* AC Record(Bugs) * * RE sizeof queue is to small * * * * * * * * * */