STR  tyvj 1068
 
描述 Description
给你两个串A,B,可以得到从A的任意位开始的子串和B匹配的长度。
给定K个询问,对于每个询问给定一个x,求出匹配长度恰为x的位置有多少个。
N,M,K<=200000
 
输入格式 Input Format
第一行三个数 N,M,K,表示A的长度、B的长度和询问数。
第二行为串A。
第三行为串B。
接下来K行,每行1个数X。
 
输出格式 Output Format
对于每个询问输出一个数。
 
样例输入 Sample Input
6 2 2
aabcde
ab
0
2
 
样例输出 Sample Output 
4
1
 
时间限制 Time Limitation
各个测试点1s
 
用KMP,匹配过程中记录在某一长度下的位置个数,最后统计答案即可
 
 
View Code
 1 var
 2   n,m,k,i,j,x:longint;
 3   a,b:ansistring;
 4   p,l,ans:array[0..200001] of longint;
 5 begin
 6   assign(input,'p1068.in');
 7   reset(input);
 8   assign(output,'p1068.out');
 9   rewrite(output);
10   
11   readln(n,m,k);
12   readln(a);
13   readln(b);
14   j:=0;
15   for i:=2 to m do
16     begin
17       while (j>0)and(b[j+1]<>b[i]) do j:=p[j];
18       if b[j+1]=b[i] then inc(j);
19       p[i]:=j;
20     end;
21   j:=0;
22   for i:=1 to n do
23     begin
24       while (j>0)and(b[j+1]<>a[i]) do j:=p[j];
25       if b[j+1]=a[i] then inc(j);
26       l[i]:=j;  //记录长度
27       if j=m then j:=p[j];
28     end;
29   for i:=1 to n do inc(ans[l[i]]);
30   for i:=m downto 1 do inc(ans[p[i]],ans[i]); //能匹配i长度,一定也能匹配p[i]长度
31   for i:=1 to k do
32     begin
33       readln(x);
34       writeln(ans[x]-ans[x+1]); //ans[x]表示x以上(包括x)的位置数,因此减去ans[x+1]就是答案
35     end;
36 
37   close(input);
38   close(output);
39 end.

 

 posted on 2012-10-13 09:36  monxine  阅读(149)  评论(0)    收藏  举报