后缀自动机

http://blog.sina.com.cn/s/blog_7812e98601012cim.html  //后缀自动机建立的详细介绍

http://www.tuicool.com/articles/Mjuu2y                          //后缀自动机学习指南(习题列表)

  1 const maxn=10008;
  2 var    a,f,rig:array[0..maxn] of longint;
  3     nt:array[0..maxn,'a'..'z'] of longint;
  4     last,sum,i:longint;
  5     s:ansistring;
  6 
  7     eg:array[0..maxn*2] of record nt,v:longint; end;
  8     lt:array[0..maxn] of longint;
  9     el:longint;
 10 
 11 procedure SAM_init;
 12 begin
 13     fillchar(f,sizeof(f),255);
 14     fillchar(nt,sizeof(nt),255);
 15     fillchar(a,sizeof(a),0);
 16     last:=0; sum:=0;
 17 end;
 18 
 19 procedure SAM_ins(ch:char);
 20 var next,p,np,q,nq:longint;
 21 begin
 22     //next:=nt[last][ch]; 添加多个串使用
 23     //if (next<>-1) and (f[last+1]<>f[next]) then begin last:=next; exit; end;
 24     inc(sum); p:=last; np:=sum; a[np]:=a[p]+1; last:=np; rig[np]:=1;
 25     while (p<>-1) and (nt[p][ch]=-1) do begin nt[p][ch]:=np; p:=f[p]; end;
 26     if p=-1 then f[np]:=0 else
 27     begin
 28         q:=nt[p][ch];
 29         if a[p]+1=a[q] then f[np]:=q else
 30         begin
 31             inc(sum); nq:=sum; a[nq]:=a[p]+1;
 32             nt[nq]:=nt[q];
 33             f[nq]:=f[q]; f[q]:=nq; f[np]:=nq;
 34             while (p<>-1) and (nt[p][ch]=q) do begin nt[p][ch]:=nq; p:=f[p]; end;
 35         end;
 36     end;
 37 end;
 38 
 39 procedure SAM_visit; //遍历所有后缀
 40 var x:longint;
 41     v:array[0..maxn] of boolean;
 42     procedure dfs(now:longint; t:string);
 43     var c:char;
 44     begin
 45         if v[now] then writeln(t);
 46         for c:='a' to 'z' do
 47         if nt[now][c]<>-1 then
 48             dfs(nt[now][c],t+c);
 49     end;
 50 begin
 51     x:=last;
 52     while x<>0 do begin v[x]:=true; x:=f[x]; end;
 53     dfs(0,'');
 54 end;
 55 
 56 procedure SAM_visit1;//遍历所有子串 并统计次数
 57     procedure dfs(now:longint; t:string);
 58     var c:char;
 59     begin
 60         if now<>0 then writeln(t,'  ',rig[now]);
 61         for c:='a' to 'z' do
 62         if nt[now][c]<>-1 then
 63             dfs(nt[now][c],t+c);
 64     end;
 65 begin
 66     dfs(0,'');
 67 end;
 68 
 69 function SAM_calc:longint; //本质不同的串
 70 var i,cnt:longint;
 71 begin
 72     cnt:=0;
 73     for i:=1 to sum do cnt:=cnt+a[i]-a[f[i]];
 74     exit(cnt);
 75 end;
 76 
 77 procedure SAM_rig;
 78     procedure dfs(u:longint);
 79     var i:longint;
 80     begin
 81         i:=lt[u];
 82         while i<>0 do
 83         begin
 84             dfs(eg[i].v);
 85             rig[u]:=rig[u]+rig[eg[i].v];
 86             i:=eg[i].nt;
 87         end;
 88     end;
 89     procedure add(u,v:longint);
 90     begin
 91         inc(el);
 92         eg[el].v:=v;
 93         eg[el].nt:=lt[u];
 94         lt[u]:=el;
 95     end;
 96 begin
 97     el:=0;
 98     fillchar(lt,sizeof(lt),0);
 99     for i:=1 to sum do add(f[i],i);
100     dfs(0);
101 end;
102 
103 begin
104     SAM_init;
105     readln(s);
106     for i:=1 to length(s) do SAM_ins(s[i]);
107     SAM_rig;
108     SAM_visit1;
109 end.
原文地址:https://www.cnblogs.com/rpSebastian/p/4565115.html