poj3261
来源:互联网 发布:美国车价 知乎 编辑:程序博客网 时间:2024/06/18 18:14
【题意】
给定一个长度为n的整数序列,求其中至少出现k次的子序列长度最长为多长
【输入】
第一行n和k
接下来n个数字描述序列
【输出】
一个数字,表示至少出现过k次的子序列最长长度
也是09年论文《后缀数组——处理字符串的有力工具》上的例题
不过不同之处是二分答案之时,判断方式是一组中是否有k个后缀
program poj3261;var n,i,j,k,s,e,mid,min,max,less:longint; dl,root,rank,sa,height,total,now,change,keep:array [-1..20001] of longint; ok:boolean;procedure qsort (s,e:longint);var i,j,k,o:longint;begin if s>=e then exit; i:=s; j:=e; k:=dl[(s+e) div 2]; while i<=j do begin while root[dl[i]]<root[k] do inc(i); while root[dl[j]]>root[k] do dec(j); if i>j then break; o:=dl[i]; dl[i]:=dl[j]; dl[j]:=o; inc(i); dec(j); end; qsort(s,j); qsort(i,e);end;begin read(n,less); for i:=1 to n do read(root[i]); for i:=1 to n do dl[i]:=i; qsort(1,n); k:=1; for i:=1 to n do if root[dl[i]]=root[dl[k]] then rank[dl[i]]:=k else begin k:=i; rank[dl[i]]:=k; end; 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-1]+total[i]; 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 change[dl[i]]<>now[rank[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 (sa[rank[i]-1]+k<=n)and(i+k<=n)and(root[i+k]=root[sa[rank[i]-1]+k]) do inc(k); height[rank[i]]:=k; end; s:=1; e:=n; while s<>e do begin mid:=s+e-(s+e) div 2; ok:=false; k:=0; for i:=2 to n do if height[i]>=mid then begin inc(k); if k>=less then begin ok:=true; break; end; end else k:=1; if ok then s:=mid else e:=mid - 1; end; writeln(s);end.
- poj3261
- poj3261
- poj3261
- POJ3261
- POJ3261----后缀数组
- poj3261(后缀数组+二分)
- POJ3261--Milk Patterns
- poj3261 Milk Patterns
- poj3261 hash~hash~
- 后缀数组+二分poj3261
- POJ3261 Milk Patterns
- 【POJ3261】字符串哈希
- 【poj3261】 Milk Patterns
- POJ3261 Milk Patterns
- POJ3261之后缀数组
- poj3261 Milk Patterns
- poj3261 Milk Patterns
- POJ3261-Milk Patterns
- Java多线程编程总结
- chrome浏览器及flash插件
- 用C设计,用C++编码
- android编译dex-preopt
- 未来的游戏盈利方式
- poj3261
- MT6573 android2.3.4 OTA包的生成研究
- android 学习基础篇---开发环境的搭建 Eclipse SDK jdk ADT
- PHP获取客户端、PHP获取服务器相关信息
- 全局监听SCREEN_ON和SCREEN_OFF的替代方法--监听屏幕解锁事件
- Chrome源码剖析【二】
- IOS 不让键盘挡住UITextField (自适应)
- Chrome源码剖析【三】
- 利用u盘制作windows7启动盘