描述 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
对于每个询问输出一个数。
分析:
需要处理的问题有:
1.需要的是长度恰好为x的,而不是可以达到x的
2.kmp中一些没有匹配过的字符的处理。如 aba和ab,就不会有从aba中的b开始匹配的时候
对于问题1,可以只记录能匹配x长度的数量(数组q),而恰好匹配x的值就是q[x]-q[x+1]
对于问题2,可以应用p数组(next),如果第i个长度可以匹配,那么p[i]也可以匹配,所以把ans[i]的值加到ans[p[i]]上
code
program haha;
var
a,b : ansistring;
p,ans,q : array[0..200002] of longint;
i,j,m,n,k : longint;
procedure init;
begin
readln(n,m,k);
readln(a);
readln(b);
j:=0;
for i:=2 to m do
begin
while (j>0) and (b[j+1]<>b[i]) do j:=p[j];
if b[j+1]=b[i] then
inc(j);
p[i]:=j;
end;
end; { init }
procedure work;
var
K : longint;
begin
j:=0;
for i:=1 to n do
begin
while (j>0) and (b[j+1]<>a[i]) do
j:=p[j];
if b[j+1]=a[i] then
inc(j);
if j=m then
j:=p[j];
q[i]:=j;//记录主串中在匹配串中匹配的长度
end;
for i:=1 to n do
inc(ans[q[i]]);
for i:=m downto 1 do
inc(ans[p[i]],ans[i]);
end; { work }
begin
assign(input,'sdf.in'); reset(input);
//assign(output,'sdf.out'); rewrite(output);
init;
work;
for I:=1 to k do
begin
readln(n);
writeln(ans[n]-ans[n+1]);
end;
close(input);
close(output);
end.