【POJ2774】Long Long Message (SA)

最长公共子串...两个字符串连在一起,中间放一个特殊字符隔开。求出height之后,枚举height,看两个后缀是不是分布于两段字符串..如果是,这个值就可以作为答案。取最大值即可。

 

  1 const maxn=200419;
  2 var
  3  c,h,rank,sa,x,y:array[0..maxn] of longint;
  4  n,k:longint;
  5  s:ansistring;
  6 
  7 function max(x,y:longint):longint; begin if x>y then exit(x) else exit(y); end;
  8 function min(x,y:longint):longint; begin if x<y then exit(x) else exit(y); end;
  9 procedure swap(var x,y:longint); var tmp:longint; begin tmp:=x;x:=y;y:=tmp; end;
 10 
 11 procedure make;
 12 var p,i,tot:longint;
 13 begin
 14  p:=1;
 15  while p<n do
 16   begin
 17    fillchar(c,sizeof(c),0);
 18    for i:= 1 to n-p do y[i]:=rank[i+p];
 19    for i:= n-p+1 to n do y[i]:=0;
 20    for i:= 1 to n do inc(c[y[i]]);
 21    for i:= 1 to n do inc(c[i],c[i-1]);
 22    for i:= 1 to n do
 23     begin
 24      sa[c[y[i]]]:=i;
 25      dec(c[y[i]]);
 26     end;
 27    fillchar(c,sizeof(c),0);
 28    for i:= 1 to n do x[i]:=rank[i];
 29    for i:= 1 to n do inc(c[x[i]]);
 30    for i:= 1 to n do inc(c[i],c[i-1]);
 31    for i:= n downto 1 do
 32     begin
 33      y[sa[i]]:=c[x[sa[i]]];
 34      dec(c[x[sa[i]]]);
 35     end;
 36    for i:= 1 to n do sa[y[i]]:=i;
 37    tot:=1;
 38    rank[sa[1]]:=1;
 39    for i:= 2 to n do
 40     begin
 41      if (x[sa[i]]<>x[sa[i-1]]) or (x[sa[i]+p]<>x[sa[i-1]+p]) then inc(tot);
 42      rank[sa[i]]:=tot;
 43     end;
 44    p:=p<<1;
 45   end;
 46  for i:= 1 to n do sa[rank[i]]:=i;
 47 end;
 48 
 49 procedure makeh;
 50 var i,j,p:longint;
 51 begin
 52  h[1]:=0; p:=0;
 53  for i:= 1 to n do
 54   begin
 55    p:=max(p-1,0);
 56    if rank[i]=1 then continue;
 57    j:=sa[rank[i]-1];
 58    while (i+p<=n) and (j+p<=n) and (s[i+p]=s[j+p]) do inc(p);
 59    h[rank[i]]:=p;
 60   end;
 61 end;
 62 
 63 procedure init;
 64 var i,tot:longint;
 65  s1:ansistring;
 66 begin
 67  readln(s);
 68  s:=s+'#';
 69  k:=length(s);
 70  readln(s1);
 71  s:=s+s1;
 72  fillchar(c,sizeof(c),0);
 73  n:=length(s);
 74  for i:= 1 to n do x[i]:=ord(s[i]);
 75  for i:= 1 to n do inc(c[x[i]]);
 76  for i:= 1 to 128 do inc(c[i],c[i-1]);
 77  for i:= 1 to n do
 78   begin
 79    sa[c[x[i]]]:=i;
 80    dec(c[x[i]]);
 81   end;
 82  rank[sa[1]]:=1;
 83  tot:=1;
 84  for i:= 2 to n do
 85   begin
 86    if x[sa[i]]<>x[sa[i-1]] then inc(tot);
 87    rank[sa[i]]:=tot;
 88   end;
 89  make;
 90  makeh;
 91 end;
 92 
 93 function range(x,y:longint):boolean;
 94 begin
 95  if (x<k) and (y>k) then exit(true);
 96  if (x>k) and (y<k) then exit(true);
 97  exit(false);
 98 end;
 99 
100 procedure solve;
101 var ans,i:longint;
102 begin
103  ans:=0;
104  for i:= 2 to n do if range(sa[i],sa[i-1]) then ans:=max(h[i],ans);
105  writeln(ans);
106 end;
107 
108 Begin
109  init;
110  solve;
111 End.

 

posted @ 2014-12-19 17:42  Ecsy  阅读(216)  评论(0编辑  收藏  举报