Find String in a Grid
时间限制: 10 Sec 内存限制: 256 MB
题目描述
You have a grid G containing R R R rows (numbered from 1 1 1 to R R R, top to bottom) and C C C columns (numbered from 1 1 1 to C C C, left to right) of uppercase characters. The character in the rth row and the cth column is denoted by Gr,c. You also have Q Q Q strings containing uppercase characters. For each of the string, you want to find the number of occurrences of the string in the grid.
An occurrence of string
S
S
S in the grid is counted if
S
S
S can be constructed by starting at one of the cells in the grid, going right
0
0
0 or more times, and then going down
0
0
0 or more times. Two occurrences are different if the set of cells used to construct the string is different. Formally, for each string
S
S
S, you would like to count the number of tuples
⟨
r
,
c
,
Δ
r
,
Δ
c
⟩
⟨r,c,Δr,Δc⟩
⟨r,c,Δr,Δc⟩ such that:
·
1
≤
r
≤
R
a
n
d
r
≤
r
+
Δ
r
≤
R
1≤r≤R \quad and\quad r≤r+Δr≤R
1≤r≤Randr≤r+Δr≤R
·
1
≤
c
≤
C
a
n
d
c
≤
c
+
Δ
c
≤
C
1≤c≤C \quad and\quad c≤c+Δc≤C
1≤c≤Candc≤c+Δc≤C
·
S
=
G
r
,
c
G
r
,
c
+
1
…
G
r
,
c
+
Δ
c
,
G
r
+
1
,
c
+
Δ
c
…
G
r
+
Δ
r
,
c
+
Δ
c
S=G_{r,c}G_{r,c+1}…G_{r,c+Δc},G_{r+1,c+Δc}…G_{r+Δr,c+Δc}
S=Gr,cGr,c+1…Gr,c+Δc,Gr+1,c+Δc…Gr+Δr,c+Δc
输入
Input begins with a line containing three integers: R C Q ( 1 ≤ R , C ≤ 500 ; 1 ≤ Q ≤ 200000 ) R \quad C \quad Q (1≤R,C≤500; 1≤Q≤200000) RCQ(1≤R,C≤500;1≤Q≤200000) representing the size of the grid and the number of strings, respectively. The next R R R lines each contains C C C uppercase characters representing the grid. The cth character on the rth line is Gr,c. The next Q Q Q lines each contains a string S containing uppercase characters. The length of this string is a positive integer not more than 200000 200000 200000. The sum of the length of all Q Q Q strings combined is not more than 200000 200000 200000.
输出
For each query in the same order as input, output in a line an integer representing the number of occurrences of the string in the grid.
样例输入
【样例1】
3 3 5
ABC
BCD
DAB
ABC
BC
BD
AC
A
【样例2】
2 3 3
AAA
AAA
A
AAA
AAAAA
样例输出
【样例1】
2
3
1
0
2
【样例2】
6
4
0
提示
Explanation for the sample input/output #1
There are
2
2
2 occurrences of ABC
, represented by the tuples
⟨
1
,
1
,
1
,
1
⟩
⟨1,1,1,1⟩
⟨1,1,1,1⟩ and
⟨
1
,
1
,
0
,
2
⟩
⟨1,1,0,2⟩
⟨1,1,0,2⟩.
There are
3
3
3 occurrences of BC
, represented by the tuples
⟨
1
,
2
,
0
,
1
⟩
⟨1,2,0,1⟩
⟨1,2,0,1⟩,
⟨
1
,
2
,
1
,
0
⟩
⟨1,2,1,0⟩
⟨1,2,1,0⟩, and
⟨
2
,
1
,
0
,
1
⟩
⟨2,1,0,1⟩
⟨2,1,0,1⟩.
There is
1
1
1 occurrence of BD
, represented by the tuple
⟨
2
,
1
,
1
,
0
⟩
⟨2,1,1,0⟩
⟨2,1,1,0⟩.
There is no occurrence of AC
.
There are
2
2
2 occurrences of A
, represented by the tuples
⟨
1
,
1
,
0
,
0
⟩
⟨1,1,0,0⟩
⟨1,1,0,0⟩ and
⟨
3
,
2
,
0
,
0
⟩
⟨3,2,0,0⟩
⟨3,2,0,0⟩.
思路
/*** Amber ***/
//#pragma GCC optimize(3,"Ofast","inline")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
#include <map>
#include <cmath>
#include <queue>
#include <algorithm>
#include <vector>
using namespace std;
#define ls (rt<<1)
#define rs (rt<<1|1)
typedef long long ll;
typedef pair<int,int> pii;
template <typename T>
inline void read(T &x) {
x = 0;
static int p;
p = 1;
static char c;
c = getchar();
while (!isdigit(c)) {
if (c == '-')p = -1;
c = getchar();
}
while (isdigit(c)) {
x = (x << 1) + (x << 3) + (c - 48);
c = getchar();
}
x *= p;
}
template <typename T>
inline void print(T x) {
if (x<0) {
x = -x;
putchar('-');
}
static int cnt;
static int a[50];
cnt = 0;
do {
a[++cnt] = x % 10;
x /= 10;
} while (x);
for (int i = cnt; i >= 1; i--)putchar(a[i] + '0');
puts("");
}
const double Pi=acos(-1);
const double eps=1e-6;
const int mod = 998244353;
const int inf = 0x3f3f3f3f;
const ll Inf = 0x3f3f3f3f3f3f3f3f;
const int maxn = 200010;
int n,m,q;
char s[1001][1010];
char str[2010];
int t[200010][27],tot;
int insert(char s[]) {
int p = 0;
for (int i = 0;s[i]; i++) {
int k = s[i] - 'A';
if (!t[p][k]) t[p][k] = ++tot;
p = t[p][k];
}
return p;
}
int id[maxn],h,tail,Q[maxn],fail[maxn],cnt[maxn];
void get_fail() {
h=1;
for (int i = 0; i < 26; i++) if (t[0][i]) Q[++tail] = t[0][i];
while (h <= tail) {
int i = Q[h++];
for (int j = 0; j < 26; j++) {
if (t[i][j]) {
fail[t[i][j]] = t[fail[i]][j];
Q[++tail] = t[i][j];
} else
t[i][j] = t[fail[i]][j];
}
}
}
inline void work() {
scanf("%d%d%d", &n, &m, &q);
for (int i = 1; i <= n; i++) {
scanf("%s", s[i] + 1);
}
for (int i = 1; i <= q; i++) {
scanf("%s", str);
id[i] = insert(str);
}
get_fail();
for (int i = 1; i <= n; i++) {
int p = 0;
for (int j = 1; j <= m; j++) {
int tt = p, r = 0;
for (int k = i; k <= n; k++) {
r = t[r][s[k][j] - 'A'];
tt = t[tt][s[k][j] - 'A'];
cnt[tt]++;
cnt[r]--;
if (i == 1) cnt[r]++;
}
p = t[p][s[i][j] - 'A'];
}
}
for (int i = tail; i > 0; i--) cnt[fail[Q[i]]] += cnt[Q[i]];
for (int i = 1; i <= q; i++) {
print(cnt[id[i]]);
}
}
int main() {
//freopen("1.txt","r",stdin);
int T = 1;
//read(T);
while (T--) {
work();
}
return 0;
}