对于可以覆盖的串,直接上模板。
对于不能覆盖的串,可以记录字典树中当前节点在询问串中的上一次询问的位置。然后对于不能覆盖的询问,用当前串的位置减去上一次询问字典树中当前节点的位置和当前深度比较一下就行了。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 6e5+5;
int res[maxn][2];
struct AC{
int tot, root, nex[maxn][26];
int f[maxn], deep[maxn], last[maxn];
int newnode() {
for(int i = 0; i < 26; i++) {
nex[tot][i] = -1;
}
return tot++;
}
void init() {
tot = 0;deep[0] = 0;
root = newnode();
memset(last, -1, sizeof(last));
memset(res, 0, sizeof(res));
}
int insert(char *s) {
int u = root;
for(int i = 0; i < strlen(s); i++) {
int ch = s[i]-'a';
if(nex[u][ch] == -1){
nex[u][ch] = newnode();
deep[nex[u][ch]] = deep[u] + 1;
}
u = nex[u][ch];
}
return u;
}
void getfail() {
queue<int>Q;
f[root] = root;
for(int i = 0; i < 26; i++) {
if(nex[root][i] != -1) {
f[nex[root][i]] = root;
Q.push(nex[root][i]);
}
else nex[root][i] = root;
}
while (!Q.empty()) {
int u = Q.front();Q.pop();
for(int i = 0; i < 26; i++) {
if(nex[u][i] == -1) {
nex[u][i] = nex[f[u]][i];
}
else {
f[nex[u][i]] = nex[f[u]][i];
Q.push(nex[u][i]);
}
}
}
}
void query(char *s) {
int u = root;
int len = strlen(s);
for(int i = 0; i < len; i++) {
int ch = s[i]-'a';
u = nex[u][ch];
int t = u;
while(t != root) {
res[t][0]++;
if(i-last[t] >= deep[t]) {
res[t][1]++;
last[t] = i;
}
t = f[t];
}
}
}
}ac;
char ss[maxn], s[maxn];
int op[maxn], n;
int p[maxn], T = 0;
void solve() {
ac.init();
scanf("%d", &n);
int cnt = 0;
for(int i = 1; i <= n; i++) {
scanf("%d%s", &op[i], s);
p[i] = ac.insert(s);
}
ac.getfail();
ac.query(ss);
printf("Case %d\n", ++T);
for(int i = 1; i <= n; i++) {
printf("%d\n", res[p[i]][op[i]]);
}
cout<<endl;
}
int main() {
int Case = 1;
//scanf("%d", &Case);
while(scanf("%s", ss) == 1)
solve();
}