后缀数组


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.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值