1.常见的匹配一个个匹配
2.高级一点的用KMP匹配
3.做到一道题 KMP超时 数据量挺大的
Given a string s, process q queries, each having one of the following forms:
1 i c — Change the ith character in the string to c.
2 l r y — Consider the substring of s starting at position l and ending at position r. Output the number of times y occurs as a substring in it.
Input
The first line contains an integer T (1 ≤ T ≤ 5), representing the case number.
For each case, the first line of the input contains the string s (1 ≤ |s| ≤ 10^5) of lowercase English letters.
The second line contains an integer q (1 ≤ q ≤ 10^5) — the number of queries to process.
The next q lines describe the queries and may have one of the following forms:
1 i c (1 ≤ i ≤ |s|)
2 l r y (1 ≤ l ≤ r ≤ |s|)
c is a lowercase English letter and y is a non-empty string consisting of only lowercase English letters.
The sum of |y| over all queries of second type is at most 3*10^5.
It is guaranteed that there is at least one query of second type.
All strings are 1-indexed.|s| is the length of the string s.
Output
For each query of type 2, output the required answer in a separate line.
举个栗子 还是不太会解释 能看懂就看看不懂只能自己推 要是有好的解释方法欢迎留言
abccabc
bitset 是从后面往前存的 数据做了处理,下标为1
a: ……000100010 倒着读 第1位a 第5位a
b: ……001000100 倒着读 第2位b 第6位b
c: ……0010011000 倒着读 第3,4,7位c
可以表示原字符串每个字母出现的位置
具体我在代码中解释
#include <bits/stdc++.h>
using namespace std;
const int maxn=100010;
bitset<maxn>s[27],ans;
char a[maxn],b[maxn],c[3];
int main()
{
int T;
cin>>T;
while(T--){
for(int i=0;i<27;i++){
s[i].reset();
}//清零
scanf("%s",a+1);//读取,从第一个开始
T=strlen(a+1); //计算长度
int i,j,l,r,Q,opt;
for(i=1;i<=T;i++) //开26个bitset 保存每个字母出现的位置
s[a[i]-'a'].set(i);
cin>>Q;
while(Q--){
cin>>opt;
if(opt==1){
scanf("%d%s",&j,c);
s[a[j]-'a'][j]=0; //当前字母的j位清零
s[(a[j]=c[0])-'a'][j]=1; //读入字母的j位变1
}
else {
cin>>l>>r;
scanf("%s",b);
int S=strlen(b);
if(S>r-l+1) { //长度大于区间打印0,continue
puts("0");
continue;
}
ans.set(); //全部置1
for(i=0;i<S;i++){
// printf("%d %d\n",(s[b[i]-'a']>>i).to_ulong(),i);
ans&=(s[b[i]-'a']>>i);
// printf("ans=%d\n",ans.to_ulong() );
}
// printf("%d\n", (ans>>l).count());
// printf("%d\n", (ans>>(r-S+2)).count());
printf("%d\n",(ans>>l).count()-(ans>>(r-S+2)).count());
//感觉这一个不算好理解,看看我例子中的abccabc
//l=1 r=7 s=3 b="abc"
//最后得到的结果……00100010
//每个1都表示当前开始可以匹配到abc
}
}
}
return 0;
}