参考罗穗骞神牛论文中求公共子串例题。

将两个字符串合并为一个,中间加上一个没有出现过的字符,我加上的是‘}’

然后求出height数组,并判断该height数组是否合法,如果合法就采用它来更新答案。

也是后缀数组的模板题吧。

代码:

Program poj2774;//By_Thispoet
Const
	maxn=200005;
Var
	i,j,k,m,n,p,q,sum,ans			:Longint;
	rank,sa,x,y,tmp,height			:Array[0..maxn]of Longint;
	st								:Array[0..maxn]of Char;
	pre,data						:Array[0..maxn]of Longint;
	link,last						:Array[0..maxn]of Longint;

Function Max(i,j:Longint):Longint;
begin
	if i>j then exit(i);exit(j);
end;


Procedure Sort();
begin

	k:=0;
	fillchar(link,sizeof(link),0);
	for i:=n downto 1 do 
		begin
			inc(k);pre[k]:=link[y[i]];
			link[y[i]]:=k;data[k]:=i;
		end;
	k:=0;
	for i:=0 to Max(n,30) do
		begin
			j:=link[i];
			while j<>0 do 
				begin
					inc(k);tmp[k]:=data[j];
					j:=pre[j];
				end;
		end;
	k:=0;
	fillchar(link,sizeof(link),0);
	for i:=n downto 1 do
		begin
			inc(k);pre[k]:=link[x[tmp[i]]];
			link[x[tmp[i]]]:=k;data[k]:=tmp[i];
		end;
	k:=0;
	for i:=0 to Max(n,30) do 
		begin
			j:=link[i];
			while j<>0 do 
				begin
					inc(k);tmp[k]:=data[j];
					j:=pre[j];
				end;
		end;
	for i:=1 to n do 
		begin
			sa[i]:=tmp[i];
			x[i]:=rank[sa[i]];
			y[i]:=rank[sa[i]+q];
		end;
	
end;


Function Check(i:Longint):Boolean;
begin
	if (x[i]<>x[i-1])or(y[i]<>y[i-1])then exit(true);
	exit(false);
end;


Function Judge(i:Longint):Boolean;
begin
	if (sa[i]>p)and(sa[i-1]>p)then exit(false);
	if (sa[i]<=p)and(sa[i-1]<=p)then exit(false);
	exit(true);
end;


BEGIN

	n:=0;
	while not eoln do
		begin
			inc(n);read(st[n]);
		end;
	p:=n;
	inc(n);st[n]:=chr(123);
	readln;
	while not eoln do
		begin
			inc(n);read(st[n]);
		end;

	for i:=1 to n do rank[i]:=ord(st[i])-96;
	q:=1;
	while q<=n-1 do
		begin
			for i:=1 to n do x[i]:=rank[i];
			for i:=1 to n do y[i]:=rank[i+q];
			Sort();
			rank[sa[1]]:=1;
			sum:=1;
			for i:=2 to n do
				begin
					if check(i) then inc(sum);
					rank[sa[i]]:=sum;
				end;
			if sum=n then break;
			q:=q<<1;
		end;

	fillchar(height,sizeof(height),0);
	while st[1+height[rank[1]]]=st[sa[rank[1]-1]+height[rank[1]]] do inc(height[rank[1]]);
	for i:=2 to n do
		begin
			height[rank[i]]:=Max(height[rank[i-1]]-1,0);
			while st[i+height[rank[i]]]=st[sa[rank[i]-1]+height[rank[i]]] do inc(height[rank[i]]);
		end;

	for i:=2 to n do
		if judge(i) then ans:=Max(ans,height[i]);

	writeln(ans);

END.