最长公共子串...两个字符串连在一起,中间放一个特殊字符隔开。求出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.
时间: 2024-11-06 09:34:03