CODEVS——T 1404 字符串匹配

 空间限制: 128000 KB
 题目等级 : 大师 Master
 
 
题目描述 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\n",ans[pos]);
41     }
42     return 0;
43 }

 

posted @ 2017-08-18 21:42  Aptal丶  阅读(311)  评论(0编辑  收藏  举报