poj3693
来源:互联网 发布:java反射调用方法参数 编辑:程序博客网 时间:2024/09/21 09:26
【题意】
给定一个字符串(长度不超过100000),要求输出重复次数最多的字典序最小的子串
【输入】
多组数据,每组数据一行,为一个小写字母组成的字符串
数据以#结束
【输出】
每组输出'Case *: '+重复次数最多字典序最小的子串
后缀数组求解
然后枚举重复部分的长度l
然后在l+1、2*l+1...位置枚举
若枚举到l+1若1和l+1上的字符相同,
则求1和l+1向前匹配的长度和向后匹配的长度。
然后将向前向后匹配长度相加再加上l然后div l
便是重复次数p
字典序的比较,比较一下起点的rank即可
需要注意的是向前匹配的最左端到最右端向前p*l都可以作为字符串的起点
用st算法可求出rank最小的起点
program poj3693;const ln2=1/ln(2);type arr=array [-1..100001] of longint; arra=array [0..18,0..100001] of longint;var n,i,j,k,l,max,where,t,s,e,mid,long,q,p,tot:longint; ok:boolean; root,nroot:ansistring; nrank,nheight,sa,dl,height,total,rank,now,keep,change:arr; min,dict,nmin:arra;procedure swap (var a,b:longint);var i:longint;begin i:=a; a:=b; b:=i;end;procedure solve (var rank,height:arr;root:ansistring);begin fillchar(total,sizeof(total),0); for i:=1 to n do inc(total[ord(root[i])-96]); for i:=1 to 26 do total[i]:=total[i-1]+total[i]; for i:=1 to n do rank[i]:=total[ord(root[i])-97]+1; k:=0; while 1 shl k<n do begin for i:=1 to n do if i+(1 shl k)>n then change[i]:=0 else change[i]:=rank[i+(1 shl k)]; fillchar(total,sizeof(total),0); for i:=1 to n do inc(total[change[i]]); for i:=1 to n do total[i]:=total[i]+total[i-1]; for i:=1 to n do begin dl[total[change[i]-1]+1]:=i; inc(total[change[i]-1]); end; fillchar(total,sizeof(total),0); ok:=true; for i:=1 to n do begin inc(total[rank[i]]); if total[rank[i]]=2 then ok:=false; end; if ok then break; for i:=2 to n do total[i]:=total[i]+total[i-1]; fillchar(now,sizeof(now),0); fillchar(keep,sizeof(keep),0); for i:=1 to n do begin if now[rank[dl[i]]]<>change[dl[i]] then begin now[rank[dl[i]]]:=change[dl[i]]; total[rank[dl[i]]-1]:=total[rank[dl[i]]-1]+keep[rank[dl[i]]]; keep[rank[dl[i]]]:=0; end; inc(keep[rank[dl[i]]]); rank[dl[i]]:=total[rank[dl[i]]-1]+1; end; inc(k); end; for i:=1 to n do sa[rank[i]]:=i; fillchar(height,sizeof(height),0); for i:=1 to n do begin if rank[i]=1 then continue; k:=height[rank[i-1]]-1; if k<0 then k:=0; while (i+k<=n)and(sa[rank[i]-1]+k<=n)and(root[i+k]=root[sa[rank[i]-1]+k]) do inc(k); height[rank[i]]:=k; end;end;procedure st (var height:arr;var min:arra);begin for i:=1 to n do min[0,i]:=height[i]; k:=0; while 1 shl k<n do begin for i:=1 to n do if i+(1 shl k)>n then min[k+1,i]:=min[k,i] else if min[k,i]<min[k,i+(1 shl k)] then min[k+1,i]:=min[k,i] else min[k+1,i]:=min[k,i+(1 shl k)]; inc(k); end;end;procedure dictst;begin for i:=1 to n do dict[0,i]:=i; k:=0; while 1 shl k<n do begin for i:=1 to n do if i+(1 shl k)>n then dict[k+1,i]:=dict[k,i] else if rank[dict[k,i]]<rank[dict[k,i+(1 shl k)]] then dict[k+1,i]:=dict[k,i] else dict[k+1,i]:=dict[k,i+(1 shl k)]; inc(k); end;end;function similar (a,b:longint;var min:arra;var rank,height:arr):longint;var i:longint;begin if a=b then exit(n-a+1); a:=rank[a]; b:=rank[b]; if a>b then swap(a,b); inc(a); if a=b then exit(height[a]); i:=trunc(ln(b-a)*ln2); while (i>0)and(1 shl i>=b-a+1) do dec(i); if min[i,a]<min[i,b-(1 shl i)+1] then exit(min[i,a]) else exit(min[i,b-(1 shl i)+1]);end;function similardict (a,b:longint):longint;var i:longint;begin if a=b then exit(a); i:=trunc(ln(b-a)*ln2); while (i>0)and(1 shl i>=b-a+1) do dec(i); if rank[dict[i,a]]<rank[dict[i,b-(1 shl i)+1]] then exit(dict[i,a]) else exit(dict[i,b-(1 shl i)+1]);end;begin t:=0; repeat readln(root); if root='#' then break; inc(t); n:=length(root); tot:=0; solve(rank,height,root); st(height,min); nroot:=root; for i:=1 to n do nroot[i]:=root[n-i+1]; solve(nrank,nheight,nroot); st(nheight,nmin); dictst; max:=1; long:=1; where:=1; for i:=2 to n do if root[i]<root[where] then where:=i; for l:=1 to n div 2 do if n div l >= max then for i:=1 to n div l do if n div l - i + 3>=max then begin if i*l+1>n then continue; if root[(i-1)*l+1]<>root[i*l+1] then continue; s:=(i-1)*l+1-similar(n-(i-1)*l+1,n-i*l+1,nmin,nrank,nheight); k:=similar(s,s+l,min,rank,height)+l; q:=k div l; if q>=max then begin p:=similardict(s,s+k-q*l); if (q>max)or ((q=max)and(rank[where]>rank[p])) then begin max:=q; where:=p; long:=l; end; end; end; write('Case ',t,': '); for i:=where to where+max*long-1 do write(root[i]); writeln; until false;end.
- poj3693
- poj3693
- 【后缀数组,RMQ】poj3693
- 后缀数组 poj3693
- poj3693 Maximum repetition substring
- poj3693之后缀数组
- POJ3693后缀数组+RMQ
- poj3693 Maximum repetition substring
- poj3693 后缀数组+RMQ
- poj3693 Maximum repetition substring
- 后缀数组小结--poj2406,poj3693,poj2774,poj1743
- POJ3693 Maximum repetition substring 后缀数组
- poj3693 Maximum repetition substring 后缀数组+RMQ
- POJ3693:Maximum repetition substring(后缀数组+RMQ)
- poj3693——后缀数组+RMQ
- poj3693 Maximum repetition substring (后缀数组+rmq)
- POJ3693 Maximum repetition substring 后缀数组
- poj3693后缀数组(插点)
- Ext4下 grid 里面的checkbox,checkbox的事件及toolbar设置
- [HTML5]Application Cache使用中需要注意的事项
- 捕捉屏幕字段值
- 用C#创建Windows服务(Windows Services)
- C#笔记
- poj3693
- web 工程下 java操作属性文件保存在classes下的读写操作
- OpenCVS 2.3.1在VS2010里面的配置
- 扩展Windows 7内存 巧用ReadyBoost提速
- 解决:启动tomcat的时候报这样的错误:java.lang.Exception: Socket bind failed: [730048] ?????????×???(Э?é/??????/???)
- 12306网上订票易,网下改票难。
- DLL破解步骤
- sybase 基本语法,存储过程,触发器
- 取消ctrl+alt+left旋转桌面