var
sa,tsa,r,tr,sum,h:array[0..200010]of longint;
s:ansistring;
i,n:longint;
procedure make_height;
var
k,i,j:longint;
begin
k:=0;
for i:=1 to n do if r[i]=1 then begin h[r[i]]:=0; continue end
else begin
j:=sa[r[i]-1];
while (i+k<=n)and(j+k<=n)and(s[i+k]=s[j+k]) do inc(k);
h[r[i]]:=k; if k>0 then dec(k);
end;
end;
procedure make_sa;
var
m,i,j,p:longint;
begin
m:=128;
for i:=1 to n do begin r[i]:=ord(s[i]); inc(sum[r[i]]); end;
for i:=1 to m do inc(sum[i],sum[i-1]);
for i:=1 to n do begin sa[sum[r[i]]]:=i; dec(sum[r[i]]); end;
p:=1; tr[sa[1]]:=1;
for i:=2 to n do begin if r[sa[i]]<>r[sa[i-1]] then inc(p); tr[sa[i]]:=p; end;
for i:=1 to n do r[i]:=tr[i];
m:=p; j:=1;
while p<n do
begin
for i:=1 to m do sum[i]:=0; p:=0;
for i:=n downto 1 do if sa[i]>j then begin inc(p); tsa[p]:=sa[i]-j; end;
for i:=n downto n-j+1 do begin inc(p); tsa[p]:=i; end;
for i:=1 to n do inc(sum[r[i]]); for i:=1 to m do inc(sum[i],sum[i-1]);
for i:=1 to n do begin sa[sum[r[tsa[i]]]]:=tsa[i]; dec(sum[r[tsa[i]]]); end;
p:=1; tr[sa[1]]:=1;
for i:=2 to n do begin if (r[sa[i]]<>r[sa[i-1]])or(r[sa[i]+j]<>r[sa[i-1]+j]) then inc(p); tr[sa[i]]:=p; end;
for i:=1 to n do r[i]:=tr[i];
m:=p; j:=j << 1;
end;
end;
begin
readln(s);n:=length(s);
make_sa;
for i:=1 to n do write(sa[i],' '); writeln;
make_height;
for i:=2 to n do write(h[i],' '); writeln;
end.
后缀数组
最新推荐文章于 2024-01-14 22:02:45 发布