poj3294
首先后缀数组预处理
然后二分答案len很显然,然后考虑怎么判定
我们用左右指针顺着名次扫描一下,初始左右指针为1
根据LCP(i,j)=min(height[rank[i]+1]~height[rank[j]]) 设rank[i]<rank[j]
移动右指针扫描得到一组后缀[i,j]之间LCP>=len,h[j+1]<len
然后判断一下这组后缀是否有超过半数的原串,如果满足则记录
然后左右指针都从j+1开始
由于每个后缀最多被扫描一次判断一次,所以必然O(n)
注意多个串相连接的时候要用不同的字符作为分隔符
- var ans,x,y,sa,sum,rank,h,loc:array[..] of longint;
- v:array[..] of boolean;
- j,len,l,r,k,i,n,m,p,tot:longint;
- s,ch:ansistring;
- procedure suffix;
- begin
- fillchar(sum,sizeof(sum),);
- for i:= to n do
- begin
- y[i]:=ord(s[i]);
- inc(sum[y[i]]);
- end;
- m:=;
- for i:= to m do
- sum[i]:=sum[i-]+sum[i];
- for i:=n downto do
- begin
- sa[sum[y[i]]]:=i;
- dec(sum[y[i]]);
- end;
- p:=;
- rank[sa[]]:=;
- for i:= to n do
- begin
- if (y[sa[i]]<>y[sa[i-]]) then inc(p);
- rank[sa[i]]:=p;
- end;
- m:=p;
- j:=;
- while m<n do
- begin
- fillchar(sum,sizeof(sum),);
- y:=rank;
- p:=;
- for i:=n-j+ to n do
- begin
- inc(p);
- x[p]:=i;
- end;
- for i:= to n do
- if sa[i]>j then
- begin
- inc(p);
- x[p]:=sa[i]-j;
- end;
- for i:= to n do
- begin
- rank[i]:=y[x[i]];
- inc(sum[rank[i]]);
- end;
- for i:= to m do
- inc(sum[i],sum[i-]);
- for i:=n downto do
- begin
- sa[sum[rank[i]]]:=x[i];
- dec(sum[rank[i]]);
- end;
- p:=;
- rank[sa[]]:=;
- for i:= to n do
- begin
- if (y[sa[i]]<>y[sa[i-]]) or (y[sa[i]+j]<>y[sa[i-]+j]) then inc(p);
- rank[sa[i]]:=p;
- end;
- m:=p;
- j:=j shl ;
- end;
- h[]:=;
- p:=;
- for i:= to n do
- begin
- if rank[i]= then continue;
- j:=sa[rank[i]-];
- while (i+p<=n) and (j+p<=n) and (s[i+p]=s[j+p]) do inc(p);
- h[rank[i]]:=p;
- if p> then dec(p);
- end;
- end;
- function solve(l,r:longint):boolean;
- var i,t:longint;
- begin
- fillchar(v,sizeof(v),false);
- t:=;
- for i:=l to r do
- if (loc[sa[i]]<>-) then
- if not v[loc[sa[i]]] then
- begin
- inc(t);
- v[loc[sa[i]]]:=true;
- end;
- if t>k shr then exit(true) else exit(false);
- end;
- function check(len:longint):boolean;
- var b,e,i:longint;
- fl:boolean;
- begin
- fl:=false;
- b:=;
- e:=;
- for i:= to n do
- begin
- if h[i]>=len then inc(e)
- else begin
- if solve(b,e) then
- begin
- if not fl then tot:=;
- fl:=true;
- inc(tot);
- ans[tot]:=sa[b];
- end;
- b:=i;
- e:=i;
- end;
- end;
- if b<e then //注意收尾
- begin
- if solve(b,e) then
- begin
- if not fl then tot:=;
- inc(tot);
- fl:=true;
- ans[tot]:=sa[b];
- end;
- end;
- exit(fl);
- end;
- begin
- readln(k);
- while k<> do
- begin
- s:='';
- r:=;
- m:=;
- for i:= to k do
- begin
- readln(ch);
- if r<length(ch) then r:=length(ch);
- for j:= to length(ch) do
- begin
- inc(m);
- loc[m]:=i;
- end;
- inc(m);
- loc[m]:=-;
- s:=s+ch+chr(i);
- end;
- n:=length(s);
- suffix;
- l:=;
- len:=;
- while l<=r do
- begin
- m:=(l+r) shr ;
- if check(m) then
- begin
- len:=m;
- l:=m+;
- end
- else r:=m-;
- end;
- if k= then
- begin
- writeln(s);
- writeln;
- end
- else if len= then
- begin
- writeln('?');
- writeln;
- end
- else begin
- for i:= to tot do
- begin;
- for j:=ans[i] to ans[i]+len- do
- write(s[j]);
- writeln;
- end;
- writeln;
- end;
- readln(k);
- end;
- end.
poj3294的更多相关文章
- 【POJ3294】 Life Forms (后缀数组+二分)
Life Forms Description You may have wondered why most extraterrestrial life forms resemble humans, d ...
- 【poj3294】 Life Forms
http://poj.org/problem?id=3294 (题目链接) 题意 给定 n 个字符串,求出现在不小于 k 个字符串中的最长子串. Solution 后缀数组论文题.. 将 n 个字符串 ...
- POJ3294 Life Forms —— 后缀数组 最长公共子串
题目链接:https://vjudge.net/problem/POJ-3294 Life Forms Time Limit: 5000MS Memory Limit: 65536K Total ...
- 【POJ3294】Life Forms(后缀数组,二分)
题意: n<=100 len[i]<=1000 思路:这是一道论文题 ..]of longint; ch:..]of ansistring; n,n1,l,r,mid,last,i,j,m ...
- poj3294 出现次数大于n/2 的公共子串
Life Forms Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 13063 Accepted: 3670 Descr ...
- POJ3294 Life Forms(后缀数组)
引用罗穗骞论文中的话: 将n 个字符串连起来,中间用不相同的且没有出现在字符串中的字符隔开,求后缀数组.然后二分答案,用和例3 同样的方法将后缀分成若干组,判断每组的后缀是否出现在不小于k 个的原串中 ...
- poj3294 Life Forms(后缀数组)
[题目链接] http://poj.org/problem?id=3294 [题意] 多个字符串求出现超过R次的最长公共子串. [思路] 二分+划分height,判定一个组中是否包含不小于R个不同字符 ...
- poj3294 --Life Forms
Life Forms Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 12483 Accepted: 3501 Descr ...
- Life Forms (poj3294 后缀数组求 不小于k个字符串中的最长子串)
(累了,这题做了很久!) Life Forms Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 8683 Accepted ...
随机推荐
- C# QRCode、DataMatrix和其他条形码的生成和解码软件
今天制造了一个C#的软件,具体是用于生成二维码和条形码的,包括常用的QRCode.DataMatrix.Code128.EAN-8等等. 使用的第三方类库是Zxing.net和DataMatrix.n ...
- dhcp源码编译支持4G上网卡
1. tar xvzf dhcp-4.2.5-P1.tar.gz 2. ./configure --host=arm-linux ac_cv_file__dev_random=yes 3. vi bi ...
- Spring MVC 中的 forward 和 redirect
Spring MVC 中,我们在返回逻辑视图时,框架会通过 viewResolver 来解析得到具体的 View,然后向浏览器渲染.假设逻辑视图名为 hello,通过配置,我们配置某个 ViewRes ...
- ubuntu14.04使用wubi安装出错
使用wubi安装后,进入系统是总是提示/分区加载异常,无法正常进入系统. 参考解决方案来自 http://jingyan.baidu.com/article/0aa22375bbffbe88cc0d6 ...
- ASP.NET 相关小知识
后台修改前台html控件属性 添加 runat=server ,后台获取// 客户端隐藏 a.Attributes[ "style "] = "display:none ...
- 2013年10月13日学习:SQL通过图形化界面创建表
通过SQL2005创建表的方式有两种: 1.通过图形化用户界面来创建表.比较容易出问题,不稳定,容易点错了.不推荐 2.通过命令来创建.大牛都是这样做的,比较好. 通过图形化界面创建:以创建员工表为例 ...
- .NET多线程同步方法详解
.NET多线程同步方法详解(一):自由锁(InterLocked) .NET多线程同步方法详解(二):互斥锁(lock) NET多线程同步方法详解(三):读写锁(ReadWriteLock) .NET ...
- (五)Struts2 标签
所有的学习我们必须先搭建好Struts2的环境(1.导入对应的jar包,2.web.xml,3.struts.xml) 第一节:Struts2 标签简介 Struts2 自己封装了一套标签,比JSTL ...
- npm install express -g出错
npm ERR! Windows_NT npm ERR! argv "C:\\Program Files\\nodejs\\node.exe" "C:\\Program ...
- jquery前端性能优化(持续添加。。。)
1.选择器的使用 (1)$('#id') 使用id来定位dom元素是性能最高的方法.jQuery底层将直接调用本地方法document.getElementById().如果id直接可以找到所要对 ...