题意:求两个字符串的最长公共子串
n<=1000
思路:这是一道论文题
1 var x,y,sa,rank,wc,wd,a,height:array[0..210000]of longint; 2 n,l1,l2,i,ans,m,l,r:longint; 3 ch:ansistring; 4 5 procedure swap(var x,y:longint); 6 var t:longint; 7 begin 8 t:=x; x:=y; y:=t; 9 end; 10 11 function max(x,y:longint):longint; 12 begin 13 if x>y then exit(x); 14 exit(y); 15 end; 16 17 function cmp(a,b,l:longint):boolean; 18 begin 19 exit((y[a]=y[b])and(y[a+l]=y[b+l])); 20 end; 21 22 procedure getsa(n:longint); 23 var i,j,p:longint; 24 begin 25 for i:=0 to n-1 do 26 begin 27 x[i]:=a[i]; 28 inc(wc[a[i]]); 29 end; 30 for i:=1 to m-1 do wc[i]:=wc[i-1]+wc[i]; 31 for i:=n-1 downto 0 do 32 begin 33 dec(wc[x[i]]); 34 sa[wc[x[i]]]:=i; 35 end; 36 j:=1; p:=1; 37 while p<n do 38 begin 39 p:=0; 40 for i:=n-j to n-1 do 41 begin 42 y[p]:=i; inc(p); 43 end; 44 for i:=0 to n-1 do 45 if sa[i]>=j then begin y[p]:=sa[i]-j; inc(p); end; 46 for i:=0 to n-1 do wd[i]:=x[y[i]]; 47 for i:=0 to m-1 do wc[i]:=0; 48 for i:=0 to n-1 do inc(wc[wd[i]]); 49 for i:=1 to m-1 do wc[i]:=wc[i-1]+wc[i]; 50 for i:=n-1 downto 0 do 51 begin 52 dec(wc[wd[i]]); 53 sa[wc[wd[i]]]:=y[i]; 54 end; 55 for i:=0 to n do swap(x[i],y[i]); 56 p:=1; x[sa[0]]:=0; 57 for i:=1 to n-1 do 58 if cmp(sa[i-1],sa[i],j) then x[sa[i]]:=p-1 59 else begin x[sa[i]]:=p; inc(p); end; 60 j:=j*2; 61 m:=p; 62 end; 63 end; 64 65 procedure getheight(n:longint); 66 var i,j,k:longint; 67 begin 68 for i:=1 to n do rank[sa[i]]:=i; 69 k:=0; 70 for i:=0 to n-1 do 71 begin 72 if k>0 then dec(k); 73 j:=sa[rank[i]-1]; 74 while a[i+k]=a[j+k] do inc(k); 75 height[rank[i]]:=k; 76 end; 77 end; 78 79 begin 80 assign(input,'poj2774.in'); reset(input); 81 assign(output,'poj2774.out'); rewrite(output); 82 readln(ch); 83 l1:=length(ch); 84 for i:=0 to l1-1 do a[i]:=ord(ch[i+1]); 85 a[l1]:=1; 86 readln(ch); 87 l2:=length(ch); 88 for i:=l1+1 to l1+l2 do a[i]:=ord(ch[i-l1]); 89 n:=l1+l2+1; a[n]:=0; m:=300; 90 getsa(n+1); 91 getheight(n); 92 inc(n); 93 for i:=2 to n do 94 begin 95 l:=sa[i-1]+1; r:=sa[i]+1; 96 if l>r then swap(l,r); 97 if (l<=l1)and(r>=l1+2) then ans:=max(ans,height[i]); 98 end; 99 100 writeln(ans); 101 102 close(input); 103 close(output); 104 end.