Find String in a Grid

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 1rRandrr+ΔrR
· 1 ≤ c ≤ C a n d c ≤ c + Δ c ≤ C 1≤c≤C \quad and\quad c≤c+Δc≤C 1cCandcc+ΔcC
· 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+1Gr,c+Δc,Gr+1,c+ΔcGr+Δ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(1R,C500;1Q200000) 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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值