$(709/3775)$
将字符串$S=S_0+S_1+S_2+…+S_{n-1}$循环位移$k$次后得到$S(k)=S_{k\bmod n }+…+S_{n-1}+S+0+…+S_{(k-1)\bmod n}$。
定义$[A]={A(k),k\in N}$。给出$T$组串$A,B$,询问$B$有多少个子串在$[A]$中。
- $|A|\leq |B|$
- $\sum|B|\leq 1048576$
记字符串$A$的长度是$n$,将字符串$A$转变为首尾相连的样子($A=A+A.substr(1,n-1)$),并计算其中每个长度为$n$的哈希值,用map存值,再对字符串$B$进行哈希,同样也对长度为$n$的子串计算哈希值,若有符合的则计数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
| ll ha[maxn], hb[maxn];
ll pwr[maxn];
void solve() {
string a, b;cin >> a >> b;
ll n = a.size();
a = a.substr(1, n - 1) + a;
ll la = a.size(), lb = b.size();
a = " " + a, b = " " + b;
pwr[0] = 1;
map<ll, bool>mp;
for (ll i = 1;i <= la;i++) {
ha[i] = ha[i - 1] * bas1 + a[i];
pwr[i] = pwr[i - 1] * bas1;
if (i - n >= 0) {
ll x = ha[i] - ha[i - n] * pwr[n];
mp[x] = true;
}
}
ll ans = 0;
for (ll i = 1;i <= lb;i++) {
hb[i] = hb[i - 1] * bas1 + b[i];
if (i - n >= 0) {
ll x = hb[i] - hb[i - n] * pwr[n];
if (mp.count(x)) {
ans++;
}
}
}
cout << ans << endl;
}
|
$(991/1659)$