先贴这里,免得忘了
program sa;
type int=longint;
var
i,j,k,m,n,l,max:int;
a,b,c,d,x,r:array[0..1000000]of int;
ch:char;
procedure main;
begin
l:=1;
repeat
for i:=0 to max do begin b[i]:=0;c[i]:=0;end;
for i:=1 to n do begin inc(b[a[i]]);inc(c[a[i+l]]);end;
for i:=1 to max do begin inc(b[i],b[i-1]);inc(c[i],c[i-1]);end;
for i:=1 to n do begin d[c[a[i+l]]]:=i;dec(c[a[i+l]]);end;
for i:=n downto 1 do begin k:=d[i];r[b[a[k]]]:=d[i];dec(b[a[k]]);end;
max:=0;
for i:=1 to n do begin
if(a[r[i-1]]<>a[r[i]])or(a[r[i-1]+l]<>a[r[i]+l])then inc(max);
x[r[i]]:=max;
end;
for i:=1 to n do a[i]:=x[i];
l:=l<<1;
until max=n;
end;
begin
assign(input,'sa.in');reset(input);
assign(output,'sa.out');rewrite(output);
while not eoln do begin
inc(n);read(ch);a[n]:=ord(ch);
if a[n]>max then max:=a[n];
end;
main;
for i:=1 to n do writeln(a[i]);
close(input);close(output);
end.
如果使用指针实现X,A的功能就可以少一个循环,应该会更快一点
最长公共子串:
program sa;
type int=longint;
var
l,i,j,k,m,n,max,ans:int;
a,b,c,d,r,x,h,st:array[0..500000]of int;
ch:char;
procedure main;
begin
l:=1;max:=200;
repeat
for i:=0 to max do begin c[i]:=0;b[i]:=0;end;
for i:=1 to n do begin inc(b[a[i]]);inc(c[a[i+l]]);end;
for i:=1 to max do begin inc(b[i],b[i-1]);inc(c[i],c[i-1]);end;
for i:=1 to n do begin d[c[a[i+l]]]:=i;dec(c[a[i+l]]);end;
for i:=n downto 1 do begin r[b[a[d[i]]]]:=d[i];dec(b[a[d[i]]]);end;
max:=0;
for i:=1 to n do begin
if(a[r[i]]<>a[r[i-1]])or(a[r[i]+l]<>a[r[i-1]+l])then inc(max);
x[r[i]]:=max;
end;
for i:=1 to n do a[i]:=x[i];
l:=l<<1;
until max=n;
for i:=1 to n do b[a[i]]:=i;
for i:=1 to n do begin
if h[i-1]>0 then h[i]:=h[i-1]-1;
while st[b[a[i]-1]+h[i]]=st[i+h[i]] do inc(h[i]);
end;
for i:=1 to n do x[a[i]]:=h[i];
for i:=2 to n do if((b[i]<m)xor(b[i-1]<m))and(ans<x[i])
then ans:=x[i];
end;//a->rank,b->sa,h->h,x->height
begin
assign(input,'data.txt');reset(input);
assign(output,'ans.txt');rewrite(output);
while not eoln do begin read(ch);inc(n);st[n]:=ord(ch);end;
m:=n+1;readln;
inc(n);st[n]:=200;
while not eoln do begin read(ch);inc(n);st[n]:=ord(ch);end;
a:=st;main;
write(ans);
close(input);close(output);
end.