您的位置:首页 > 其它

POJ2774 Long Long Message——后缀数组——pku2774

2011-10-03 11:21 357 查看
参考罗穗骞神牛论文中求公共子串例题。

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

然后求出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
);
end;
p:=n;
inc(n);st
:=chr(123);
readln;
while not eoln do
begin
inc(n);read(st
);
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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: