现在的位置: 首页 > 综合 > 正文

tyvj1068 STR

2012年05月27日 ⁄ 综合 ⁄ 共 1129字 ⁄ 字号 评论关闭

给你两个串A,B,可以得到从A的任意位开始的子串和B匹配的长度。
给定K个询问,对于每个询问给定一个x,求出匹配长度恰为x的位置有多少个。
N,M,K<=200000

字符串的处理,用KMP喽,首先求出模式串B的next[],然后进行一遍AB匹配,记录a[i]匹配的最大长度,那么如果a[i]可以匹配l[i]的长度,answer[i]表示匹配长度为i的串的数量,则answer[next[i]]的匹配长度也是满足answer[i]的,所以只要倒着循环一遍,把answer[next[i]]加到answer[i]中即可。这时的answer[i]包含了长度为i+1的情况,所以要输出answer[k]-answer[k+1].

View Code

 1 program tyvj1068(input,output);
2 var
3 a,b : ansistring;
4 next,l : array[0..201000] of longint;
5 answer : array[0..201000] of longint;
6 i,j,x : longint;
7 n,m,k : longint;
8 ch : char;
9 begin
10 readln(n,m,k);
11 a:='';
12 b:='';
13 for i:=1 to n do
14 begin
15 read(ch);
16 a:=a+ch;
17 end;
18 readln;
19 for i:=1 to m do
20 begin
21 read(ch);
22 b:=b+ch;
23 end;
24 readln;
25 fillchar(next,sizeof(next),0);
26 next[1]:=0;
27 j:=0;
28 for i:=2 to m do
29 begin
30 while (j>0)and(b[j+1]<>b[i]) do
31 j:=next[j];
32 if b[j+1]=b[i] then
33 inc(j);
34 next[i]:=j;
35 end;
36 j:=0;
37 for i:=1 to n do
38 begin
39 while (j>0)and(b[j+1]<>a[i]) do
40 j:=next[j];
41 if b[j+1]=a[i] then
42 inc(j);
43 l[i]:=j;
44 if j=m then
45 j:=next[j];
46 end;
47 fillchar(answer,sizeof(answer),0);
48 for i:=1 to n do
49 inc(answer[l[i]]);
50 for i:=n downto 1 do
51 inc(answer[next[i]],answer[i]);
52 for i:=1 to k do
53 begin
54 readln(x);
55 writeln(answer[x]-answer[x+1]);
56 end;
57 end.

抱歉!评论已关闭.