Test Instructions
Given string s S and T t
Two kinds of operations:
1. Modify the character of a position in S S string
2. Ask how many times T-t strings appear in a substring of s s
| t|≤10 | T|\le10
If there is no modification, we can build a fail fail pointer to T T, then KMP in S S and record which locations match the complete T-t string, which is equivalent to a 01 array, asking for the interval of the 01 array and can be implemented simply with a tree-like array. Such a query is O (logn) O (\log N).
When a character is modified, it is obvious that the 01 array is affected by a maximum of 10 positions, that is, each time the action is modified to KMP and modify the 01 array of the corresponding position. Such a modification is O (logn) O (\log n), the constant is about 10. Thus the overall complexity O (QLOGN) O (q\log N). Code
#include <bits/stdc++.h> #define KN 100010LL #define KL 100010LL #define LB (p& (-P)) int q,n,m,fail[20],
C[KL];
BOOL OK[KL];
Char s[kl],t[20]; inline void ins (int p,int W) {for (;p <=n;p+=lb) c[p]+=w;} inline int sum (int p) {int ret=0;for (;p >0;p-=lb) re
T+=c[p];return ret;
} inline void Getfail () {int I, p = 0;
FAIL[1] = 0;
for (i=2;i<=m;i++) {while (P&&t[p+1]!=t[i]) p=fail[p];
p+= (T[p+1]==t[i]), fail[i] = p;
}} inline void Query (int l,int r) {L + = m-1;
if (l<=r) printf ("%d\n", sum (r)-sum (L-1));
Else puts ("0");
} inline void Change (int p,char c) {if (c = = S[p]) return;
S[P] = c;
int L = p-m+1, r = p+m-1, I;
if (l<1) L = 1;
if (r > N) r = N;
int pos = p;
p = 0;
for (i = l;i <= r;i + +) {while (P && t[p+1]!=s[i]) p = fail[p];
p + = (t[p+1]==s[i]); if (I >= POS) {if (p = = m) {if (!ok[i]) Ok[i]=truE,ins (i,1);
} else {if (Ok[i]) ok[i] = False, Ins (i,-1);
}}}} inline void work () {int p, I, J, K;
char mode, C;
scanf ("%d%s%s", &q,s+1,t+1);
N=strlen (s+1);
M=strlen (t+1);
Getfail ();
memset (ok,0,sizeof OK);
memset (c,0,sizeof C);
p = 0;
for (i=1;i<=n;i++) {while (P && t[p+1]!=s[i]) p = fail[p];
p + = (t[p+1]==s[i]);
if (p = = m) ok[i]=true,ins (i,1);
} while (q-->0) {while (Mode=getchar (), mode!= ' Q ' &&mode!= ' C ');
if (mode = = ' Q ') {scanf ("%d%d", &j,&k);
Query (J,K);
} else {scanf ("%d", &j);
while (C=getchar (),c< '! ');
Change (J,C);
}} puts ("");}
int main () {int T;
scanf ("%d", &t);
while (t-->0) work ();
return 0; }