https://nanti.jisuanke.com/t/16956
写了好多次,用我自己的kmp写法一直 tle。
用kmp处理母串中每个位置 失配模式串的位置
然后用树状数组处理,(据说线段树会卡??)
kmp还要好好学。。
#include<bits/stdc++.h>
using namespace std;
/*
每次维护保存一个 当前位置失配的位置。
(相当于维护一个next,因为next是模式串的 最长的 前缀和后缀一起出现的地方,所以我们也可以理解为他是失配的地方)
*/
const int maxn=1e5+2000;
int sum[maxn];
int cc[maxn];
char s[maxn];
char t[maxn];
int len1;
int len2;
int lowbit(int x){
return x&(-x);
}
void add(int u,int s){
while(u<maxn){
sum[u]+=s;
u+=lowbit(u);
}
}
int sums(int u){
int all=0;
while(u){
all+=sum[u];
u-=lowbit(u);
}
return all;
}
int nex[maxn];
/*void next(){
//int len=s2.length();
int i=0;//下面就要计算 next数组了
int k=-1;//记录最大next
nex[0]=0;
while(i<len2){
if(k==-1||t[i]==t[k]){
i++;k++;
nex[i]=k;//记住,nex i是i-1串的 最长前后缀。
}
else
k=nex[k];//递归,在最长 前后缀中间继续寻找。
}
}
void update(int len3){
int k;
if(len3>0)
k=cc[len3-1];
else
k=0;
//cout<<"ini"<<k<<endl;
//cout<<len1<<"???"<<len3<<endl;
for(int i=len3;i<len1&&i<len3+len2;i++){
if(cc[i]==len2)add(i+1,-1);
while(k>0&&s[i]!=t[k])
k=nex[k];
if(s[i]==t[k])
k++;
if(k==len2)
add(i+1,1);
cc[i]=k;
}
//puts("ccccc");
//for(int i=0;i<len1;i++)
// cout<<cc[i]<<" ";
//cout<<endl;
}
int getsum(){
//int len1=strlen(s);
//int len2=strlen(t);
int k=0;
for(int i=0;i<len1;i++){
while(k>0&&s[i]!=t[k])
k=nex[k];
if(s[i]==t[k])
k++;
if(k==len2)
add(i+1,1);
cc[i]=k;
}
}*/
void KMP()
{
int len=strlen(t);
nex[0]=0;
for(int i=1,k=0;i<len;i++)
{
while(k>0 && t[i]!=t[k]) k=nex[k-1];
if(t[i]==t[k]) k++;
nex[i]=k;
}
}
void getCal(){
len1 = strlen(s);
len2 = strlen(t);
for(int i=0,k=0;i<len1;i++) {
while(k>0&& s[i]!=t[k]) k=nex[k-1];
if(s[i]==t[k]) k++;
cc[i] = k;
if(k==len2) add(i+1,1);
}
}
void update(int pos){
int k=0;
if(pos>0) k=cc[pos-1];
for(int i=pos;i<pos+len2 && i<len1;i++)
{
if(cc[i]==len2) add(i+1,-1);
while(k>0 && s[i]!=t[k]) k=nex[k-1];
if(s[i]==t[k]) k++;
if(k==len2) add(i+1,1);
cc[i]=k;
}
}
void init(){
memset(cc,0,sizeof(cc));
memset(sum,0,sizeof(sum));
}
int main()
{ //ios::sync_with_stdio(false);
int T,m,a,b;
char ch,ch2;
scanf("%d",&T);
while(T--){
init();
scanf("%d",&m);
getchar();
scanf("%s",s);
scanf("%s",t);
KMP();
len1=strlen(s);
len2=strlen(t);
getCal();
for(int i=0;i<m;i++){
scanf(" %c",&ch);
if(ch=='Q'){
scanf("%d%d",&a,&b);
//cout<<a<<" "<<b<<endl;
if(b-a+1<len2){
puts("0");
continue;
}
else
printf("%d\n",sums(b)-sums(a+len2-2));
}
else{
getchar();
scanf("%d",&a);
getchar();
scanf("%c",&ch2);
s[a-1]=ch2;
update(a-1);
}
}
puts("");
}
return 0;
}