题目描述 Description
给你两个串A,B,可以得到从A的任意位开始的子串和B匹配的长度。
给定K个询问,对于每个询问给定一个x,求出匹配长度恰为x的位置有多少个。
N,M,K<=200000
输入描述 Input Description
第一行三个数 N,M,K,表示A的长度、B的长度和询问数。
第二行为串A。
第三行为串B。
接下来K行,每行1个数X。
输出描述 Output Description
对于每个询问输出一个数。
样例输入 Sample Input
6 2 2
aabcde
ab
0
2
样例输出 Sample Output
4
1
数据范围及提示 Data Size & Hint
各个测试点1s
kmp得出ans[],然后考虑将串分解,,倒序累加ans[next[i]],,此时的ans[i]是>=i位的数量,所以最后还要处理为ans[i]-=ans[i+1]
1 #include <algorithm> 2 #include <cstring> 3 #include <cstdio> 4 5 using namespace std; 6 7 const int N(200000+5); 8 int n,m,k,lb,la; 9 int p[N],ans[N]; 10 char a[N],b[N]; 11 12 inline void Get_next() 13 { 14 for(int i=2,j=0;i<=lb;p[i++]=j) 15 { 16 for(;b[i]!=b[j+1]&&j>0;) j=p[j]; 17 if(b[i]==b[j+1]) j++; 18 } 19 } 20 inline void kmp() 21 { 22 for(int i=1,j=0;i<=la;i++) 23 { 24 for(;a[i]!=b[j+1]&&j>0;) j=p[j]; 25 if(a[i]==b[j+1]) j++; 26 ans[j]++; 27 } 28 } 29 30 int main() 31 { 32 scanf("%d%d%d%s%s",&n,&m,&k,a+1,b+1); 33 la=strlen(a+1); lb=strlen(b+1); 34 Get_next(); kmp(); 35 for(int i=lb;i>0;i--) ans[p[i]]+=ans[i]; 36 for(int i=0;i<lb;i++) ans[i]-=ans[i+1]; 37 for(int pos;k--;) 38 { 39 scanf("%d",&pos); 40 printf("%d ",ans[pos]); 41 } 42 return 0; 43 }