补题链接:https://acm.hdu.edu.cn/showproblem.php?pid=7064
板子题:字符串hash
code
using namespace std;
// 2^64,让其自然溢出,相当于对2^64取mod
typedef unsigned long long ULL;
// P(进制数)一般取131/13331
const int N = 100010, P = 131;
int n, m;
char str[N];
ULL h[N], p[N];
// 求[l, r]区间的字符串的hash值
ULL get(int l, int r){
// 1 ~ (l - 1)(从高位到低位)
// 1 ~ r (从高位到低位)
// L ~ R (相当于把h[l - 1]左移动(r - (l - 1))位, 然后用h[r]减去)
return h[r] - h[l - 1] * p[r - l + 1];
}
void solve(){
scanf("%s", str + 1);
n = strlen(str + 1);
unordered_map<ULL, int> cnt;
unordered_map<ULL, int> lst;
p[0] = 1;
for(int i = 1; i <= n; i++){
h[i] = h[i - 1] * P + str[i];
p[i] = p[i - 1] * P;
}
scanf("%d", &m);
char chs[33];
ULL a[m];
for (int i = 1; i <= m; ++i) {
scanf("%s", chs + 1);
ULL hs = 0;
for (int i = 1; chs[i]; ++i) {
hs = hs * P + chs[i];
}
a[i] = hs;
cnt[hs] = 0;
lst[hs] = 0;
}
for (int len = 1; len <= 30; ++len) {
for (int i = 1; i + len - 1 <= n; ++i) {
ULL hs = get(i, i + len - 1);
if(cnt.count(hs) && lst[hs] <= i){
lst[hs] = i + len;
cnt[hs]++;
}
}
}
for (int i = 1; i <= m; ++i) {
printf("%d\n", cnt[a[i]]);
}
}
int main(){
int t;
scanf("%d", &t);
while(t--) solve();
return 0;
}