比赛 20120706 评测结果 AAAAAAAAAA
题目名称 解密 最终得分 100
用户昵称 IMSL77 运行时间 0.000 s
代码语言 Pascal 内存使用 0.00 MiB
提交时间 2012-07-06 11:56:49
显示代码纯文本
program main;
type
  integer=longint;
const
  maxn=1100000;
  pmod=10000007;
  seed=131;
var
  n,m,tot:integer;
  A,B:ansistring;
  nearA,nearB:array[1..maxn] of integer;
  hash:array[0..pmod] of integer;
  pst,pen,tick,next:array[1..maxn] of integer;
  pat:array[1..maxn] of integer;

  procedure Fopen;
  begin
    assign(input,'kriptogram.in');
    reset(input);
    assign(output,'kriptogram.out');
    rewrite(output);
  end;

  procedure Fclose;
  begin
    close(input);
    close(output);
  end;

  procedure addhashA(st,en,p:integer);
  var
    i:integer;
    code:integer;
  begin
    code:=0;
    for i:=st to en do code:=(code*seed+ord(A[i])) mod pmod;
    i:=hash[code];
    while (i>0) and (copy(A,pst[i],pen[i]-pst[i]+1)<>copy(A,st,en-st+1))
    do i:=next[i];
    if i=0 then
    begin
      inc(tot);
      pst[tot]:=st; pen[tot]:=en; tick[tot]:=p;
      next[tot]:=hash[code]; hash[code]:=tot;
    end else
    begin
      nearA[p]:=tick[i]; tick[i]:=p;
    end;
  end;

  procedure addhashB(st,en,p:integer);
  var
    i:integer;
    code:integer;
  begin
    code:=0;
    for i:=st to en do code:=(code*seed+ord(B[i])) mod pmod;
    i:=hash[code];
    while (i>0) and (copy(B,pst[i],pen[i]-pst[i]+1)<>copy(B,st,en-st+1))
    do i:=next[i];
    if i=0 then
    begin
      inc(tot);
      pst[tot]:=st; pen[tot]:=en; tick[tot]:=p;
      next[tot]:=hash[code]; hash[code]:=tot;
    end else
    begin
      nearB[p]:=tick[i]; tick[i]:=p;
    end;
  end;

  function eqA(j,i,l:integer):boolean;
  var
    p,q:integer;
  begin
    p:=nearA[i]; q:=nearB[j];
    if (p>0) and (p+l<i) then p:=0;
    if (q>0) and (q+l<j) then q:=0;
    if (p>0) then p:=i-p;
    if (q>0) then q:=j-q;
    exit(p=q);
  end;

  function eqB(j,i,l:integer):boolean;
  var
    p,q:integer;
  begin
    p:=nearB[i]; q:=nearB[j];
    if (p>0) and (p+l<i) then p:=0;
    if (q>0) and (q+l<j) then q:=0;
    if (p>0) then p:=i-p;
    if (q>0) then q:=j-q;
    exit(p=q);
  end;

  procedure Init;
  var
    st,en:integer;
  begin
    readln(A); readln(B);
    fillchar(hash,sizeof(hash),0);
    fillchar(next,sizeof(next),0);
    fillchar(nearA,sizeof(nearA),0);
    tot:=0; n:=0;
    st:=1; en:=1;
    repeat
      while (A[en]<>' ') and (A[en]<>'$') do inc(en);
      if A[en]='$' then break;
      inc(n); addhashA(st,en-1,n);
      st:=en+1; en:=st;
    until false;
    fillchar(hash,sizeof(hash),0);
    fillchar(next,sizeof(next),0);
    fillchar(nearB,sizeof(nearB),0);
    tot:=0; m:=0;
    st:=1; en:=1;
    repeat
      while (B[en]<>' ') and (B[en]<>'$') do inc(en);
      if B[en]='$' then break;
      inc(m); addhashB(st,en-1,m);
      st:=en+1; en:=st;
    until false;
  end;

  procedure KMP;
  var
    i,j:integer;
  begin
    pat[1]:=0; j:=0;
    for i:=2 to m do
    begin
      while (j>0) and not (eqB(j+1,i,j)) do j:=pat[j];
      if eqB(j+1,i,j) then inc(j);
      pat[i]:=j;
    end;
    j:=0;
    for i:=1 to n do
    begin
      while (j>0) and not (eqA(j+1,i,j)) do j:=pat[j];
      if eqA(j+1,i,j) then inc(j);
      if j=m then begin writeln(i-m+1); exit; end;
    end;
  end;

begin
  Fopen;
  Init;
  KMP;
  Fclose;
end.