标签:
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.
标签:
原文地址:http://www.cnblogs.com/rpSebastian/p/4565115.html