USACO 6.2.1 Calf Flac manacher算法

直接用一次manacher算法求最长回文就好了。

代码:

{
ID: ymwbegi1
PROG: calfflac
LANG: PASCAL
}

var
  s2:ansistring;
  r:char;
  s,s1:array[0..50000] of char;
  i,mx,po,ans,u,n,x,y:longint;
  len,num:array[0..50000] of longint;

function min(x,y:longint):longint;
begin
  if x<y then exit(x)
         else exit(y);
end;

begin
  assign(input,'calfflac.in');
  assign(output,'calfflac.out');
  reset(input);
  rewrite(output);
  while not eof do
  begin
    read(r);
    s2:=s2+r;
  end;
  for i:=1 to length(s2) do
    if (s2[i] in ['a'..'z'])or(s2[i] in ['A'..'Z']) then
    begin
      inc(n);
      if s2[i] in ['a'..'z']
        then s1[n]:=s2[i]
        else s1[n]:=chr(ord(s2[i])+32);
      num[n]:=i;
    end;
  s[0]:='!';
  s[1]:='@';
  for i:=1 to n do
  begin
    s[i*2]:=s1[i];
    s[i*2+1]:='@';
  end;
  for i:=1 to n*2+1 do
  begin
    if i<mx
      then len[i]:=min(len[i],2*po-i)
      else len[i]:=1;
    while s[i+len[i]]=s[i-len[i]] do inc(len[i]);
    if len[i]+i>mx then
    begin
      mx:=len[i]+i;
      po:=i;
    end;
    if len[i]>ans then
    begin
      ans:=len[i];
      u:=i;
    end;
  end;
  writeln(ans-1);
  x:=u-len[u]+1;
  if s[x]='@' then inc(x);
  y:=u+len[u]-1;
  if s[y]='@' then dec(y);
  for i:=num[x div 2] to num[y div 2] do
    write(s2[i]);
  writeln;
  close(input);
  close(output);
end.


你可能感兴趣的:(USACO 6.2.1 Calf Flac manacher算法)