ZOJ2006 (后缀自动机)
2015-06-10 16:16
302 查看
求一个字符串的最小表示法。
将字符串S倍长,从根走length(s)步所走路径即为最小表示法。
记所到达位置为x,则这个最小表示法的起点为a[x]-len(s)+1
将字符串S倍长,从根走length(s)步所走路径即为最小表示法。
记所到达位置为x,则这个最小表示法的起点为a[x]-len(s)+1
const maxn=20008; var T:longint; nt:array[0..maxn,'a'..'z'] of longint; a,f:array[0..maxn] of longint; sum,last:longint; s:ansistring; procedure Sam_init; begin fillchar(nt,sizeof(nt),255); fillchar(a,sizeof(a),0); fillchar(f,sizeof(f),255); sum:=0; last:=0; end; procedure Sam_ins(i:longint); var p,q,np,nq:longint; ch:char; begin ch:=s[i]; p:=last; inc(sum); np:=sum; a[np]:=a[p]+1; last:=np; while (p<>-1) and (nt[p][ch]=-1) do begin nt[p][ch]:=np; p:=f[p]; end; if p=-1 then f[np]:=0 else begin q:=nt[p][ch]; if a[p]+1=a[q] then f[np]:=q else begin inc(sum); nq:=sum; a[nq]:=a[p]+1; nt[nq]:=nt[q]; f[nq]:=f[q]; f[q]:=nq; f[np]:=nq; while (p<>-1) and (nt[p][ch]=q) do begin nt[p][ch]:=nq; p:=f[p]; end; end; end; end; procedure dfs(now,len:longint); var ch:char; begin if len=0 then begin writeln(a[now]-length(s) div 2+1); exit; end; for ch:='a' to 'z' do if nt[now][ch]<>-1 then begin dfs(nt[now][ch],len-1); exit; end; end; procedure main; var i:longint; begin readln(s); s:=s+s; Sam_init; for i:=1 to length(s) do Sam_ins(i); dfs(0,length(s) div 2); end; begin readln(T); while T>0 do begin dec(T); main; end; end.
相关文章推荐
- MSM RF Driver Configuration
- [Python]网络爬虫(四):Opener与Handler的介绍和实例应用
- message queue & event loop
- SVN的Status总结
- android fragment页面切换GridView数据不能刷新的问题
- 索引键的唯一性(1/4):堆表上的唯一与非唯一非聚集索引的区别
- iphone调用系统电话、浏览器、地图、邮件等
- 快速排序的三路划分法
- 217公斤小伙不堪重负切胃减肥
- 快速排序的三者取中划分
- Bluemix云平台实践:使用Bluemix Labs Catalog来创建应用(2)
- 最新版SDWebImage的使用
- 初识 ZeroMQ
- 截取图片
- hadoop HDFS结构
- 快速排序中小文件采用插入排序
- MDT 2013 从入门到精通之启动映像添加
- BeagleBone折腾记(一):连接你的狗板
- 快速排序的非递归实现
- 女子透支信用卡300万买奢侈品