后缀数组,,觉得没什么好讲的
可见黑书辣,白书辣什么的
觉得讲的很清楚啊
唯一一个需要理解的就是它计数排序的时候
var s:array[1..200000] of char;
sum1:array['a'..'z'] of longint;
height,sum:array[1..200000] of longint;
rank,trank,sa,tsa:Array[1..400000] of longint;
p,i,j,n,k:longint;
ch:char;
procedure init;
begin
while not(eoln) do
begin
inc(n);
read(s[n]);
end;
end;
procedure sorting(j:longint);
begin
for i:=1 to n do sum[i]:=0;
for i:=1 to n do inc(sum[rank[i+j]]);
for i:=1 to n do inc(sum[i],sum[i-1]);
for i:=n downto 1 do
begin
tsa[sum[rank[i+j]]]:=i;
dec(sum[rank[i+j]]);
end;
for i:=1 to n do sum[i]:=0;
for i:=1 to n do inc(sum[rank[i]]);
for i:=1 to n do inc(sum[i],sum[i-1]);
for i:=n downto 1 do
begin
sa[sum[rank[tsa[i]]]]:=tsa[i];
dec(sum[rank[tsa[i]]]);
end;
end;
procedure main;
begin
init;
for i:=1 to n do inc(sum1[s[i]]);
for ch:='b' to 'z' do inc(Sum1[ch],sum1[chr(ord(ch)-1)]);
for i:=n downto 1 do
begin
sa[sum1[s[i]]]:=i;
dec(sum1[s[i]]);
end;
rank[sa[1]]:=1;
p:=1;
for i:=2 to n do
begin
if s[sa[i]]<>s[sa[i-1]] then inc(p);
rank[sa[i]]:=p;
end;
j:=1;
while (j<=n) do
begin
sorting(j);
p:=1;
trank[sa[1]]:=1;
for i:=2 to n do
begin
if (rank[sa[i]]<>rank[sa[i-1]]) or (rank[sa[i]+j]<>rank[sa[i-1]+j]) then inc(p);
trank[sa[i]]:=p;
end;
for i:=1 to n do rank[i]:=trank[i];
j:=j shl 1;
end;
for i:=1 to n do write(sa[i],' ');
writeln;
i:=sa[rank[1]-1];
j:=0;
while s[i+j]=s[1+j] do inc(j);
height[rank[1]]:=j;
for i:=2 to n do
begin
if j>0 then dec(j);
k:=sa[rank[i]-1];
while (s[k+j])=(s[i+j]) do inc(j);
height[rank[i]]:=j;
end;
for i:=1 to n do write(height[i],' ');
end;
begin
main;
end.