UVA 11019 Matrix Matcher 矩阵匹配器 AC自动机 二维文本串查找二维模式串

时间:2022-01-06 23:33:38
链接:https://vjudge.net/problem/UVA-11019
lrjP218 matrix matcher
#include<bits/stdc++.h>
using namespace std;
#define P pair<int,int>
#define ms(x,y) memset(x,y,sizeof x)
#define LL long long
const int maxn = ;
const int mod = 1e9+;
const int maxnode = *+;
const int sigma_size = ;
vector<int> as[maxnode];
int cnt[][], ans;
int n, m, x, y;
struct AhoCorasickAutomata
{
int ch[maxnode][sigma_size];
int val[maxnode];
int sz;
int f[maxnode];
int last[maxnode];
void clear(){sz = ; memset(ch[],,sizeof ch[]); }
int idx(char c){return c-'a'; } void insert(char *s,int x)
{
int u = , n = strlen(s);
for(int i = ; i < n; i++){
int c = idx(s[i]);
if(!ch[u][c]){
memset(ch[sz], , sizeof ch[sz]);
val[sz] = ;
as[sz].clear();
ch[u][c] = sz++;
}
u = ch[u][c];
}
as[u].push_back(x);///存储给字符结尾,有哪些行是终点。
val[u] = ;
} void find(char *T,int row){
int n = strlen(T);
int j = ;
for(int i = ; i < n; i++){
int c = idx(T[i]);
//while(j&&!ch[j][c]) j = f[j];
j = ch[j][c];
if(val[j]) print(j,i,row);
else if(last[j]) print(last[j],i,row);
}
} void print(int j,int col,int row)
{
if(j){
//cnt[val[j]]++;
int len = as[j].size();
for(int i = ; i < len; i++){
if(row-as[j][i]>=){///cnt[row-as[j][i]][col]++这样当前找到的行,不会对自己起作用。而是对以前的起作用。
if(++cnt[row-as[j][i]][col]==x){///因为时间卡的紧,所以我没有在最外面判断。
///在这里判断节约时间。否则超时。
ans++;
} }
}
print(last[j],col,row);
}
} void getFail(){
queue<int> q;
f[] = ;
for(int c = ; c < sigma_size; c++){
int u = ch[][c];
if(u){f[u] = ; q.push(u); last[u] = ;}
} while(!q.empty()){
int r = q.front(); q.pop();
for(int c = ; c < sigma_size; c++){
int u = ch[r][c];
if(!u){
ch[r][c] = ch[f[r]][c]; continue;
}//if(!u) continue;
q.push(u);
int v = f[r];
while(v&&!ch[v][c]) v = f[v];
f[u] = ch[v][c];
last[u] = val[f[u]] ? f[u] : last[f[u]];
}
}
} } ac ;
char t[][];
char s[];
int main()
{
int T;
cin>>T;
while(T--)
{
scanf("%d%d",&n,&m);
ms(cnt,);
ac.clear();
for(int i = ; i < n; i++){
scanf("%s",t[i]);
}
scanf("%d%d",&x,&y);
for(int i = ; i < x; i++){
scanf("%s",s);
ac.insert(s,i);
}
ac.getFail();
ans = ;
for(int i = ; i < n; i++){
ac.find(t[i],i);
}
cout<<ans<<endl;
}
return ;
} /*
2
1 1
x
1 1
y
3 3
abc
bcd
cde
2 2
bc
cd */