首先后缀数组预处理
然后二分答案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的更多相关文章

  1. 【POJ3294】 Life Forms (后缀数组+二分)

    Life Forms Description You may have wondered why most extraterrestrial life forms resemble humans, d ...

  2. 【poj3294】 Life Forms

    http://poj.org/problem?id=3294 (题目链接) 题意 给定 n 个字符串,求出现在不小于 k 个字符串中的最长子串. Solution 后缀数组论文题.. 将 n 个字符串 ...

  3. POJ3294 Life Forms —— 后缀数组 最长公共子串

    题目链接:https://vjudge.net/problem/POJ-3294 Life Forms Time Limit: 5000MS   Memory Limit: 65536K Total ...

  4. 【POJ3294】Life Forms(后缀数组,二分)

    题意: n<=100 len[i]<=1000 思路:这是一道论文题 ..]of longint; ch:..]of ansistring; n,n1,l,r,mid,last,i,j,m ...

  5. poj3294 出现次数大于n/2 的公共子串

    Life Forms Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 13063   Accepted: 3670 Descr ...

  6. POJ3294 Life Forms(后缀数组)

    引用罗穗骞论文中的话: 将n 个字符串连起来,中间用不相同的且没有出现在字符串中的字符隔开,求后缀数组.然后二分答案,用和例3 同样的方法将后缀分成若干组,判断每组的后缀是否出现在不小于k 个的原串中 ...

  7. poj3294 Life Forms(后缀数组)

    [题目链接] http://poj.org/problem?id=3294 [题意] 多个字符串求出现超过R次的最长公共子串. [思路] 二分+划分height,判定一个组中是否包含不小于R个不同字符 ...

  8. poj3294 --Life Forms

    Life Forms Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 12483   Accepted: 3501 Descr ...

  9. Life Forms (poj3294 后缀数组求 不小于k个字符串中的最长子串)

    (累了,这题做了很久!) Life Forms Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 8683   Accepted ...

随机推荐

  1. SSO单点登录之数据同步

    完成单点登录,我们便可以通过只登录一个账号,来访问不同系统,然而会遇到以下问题. 1. 通过A站登录的用户访问B站,在B站并没有真实用户,此时如果在B站新建用户,则可能造成用户信息不全,或者数据冲突等 ...

  2. 源码心德`Context`类

    Context,中文直译为“上下文”,SDK中对其说明如下: Interface to global information about an application environment. Thi ...

  3. 写一个最简单的 Server

    import java.net.*;import java.io.*;public class Server{ public static void main(String[] args) throw ...

  4. SQL语句一之建库

    USE master --转到系统表goIF EXISTS(SELECT *  FROM sysdatabases WHERE name ='Test') --查询是否存在Test数据库DROP DA ...

  5. Linq- ExcuteQuery用法

    DataContext.ExecuteQuery<TResult> 方法 (String, Object[]) 语法: public IEnumerable<TResult> ...

  6. 虚拟机 Linux 系统增加换页空间

    想在虚拟机里面安装oracle10g,发现默认的swap交换空间不满足最低要求,因为我分配的物理内存是1G,那么就按照要求需要2G的swap交换空间,默认只有1G的交换空间.添加swap交换空间的步骤 ...

  7. Analyze 静态分析工具中显示 大量的CF类型指针 内存leak 问题, Core Foundation 类型指针内存泄漏

    Analyze 静态分析工具中显示 大量的CF类型指针 内存leak 问题   今天使用Analyze 看了下项目,   解决办法,项目中使用了ARC,OC的指针类型我们完全不考虑release的问题 ...

  8. npm 好用工具 for 前端

    1. caniuse npm install -g caniuse-cmd

  9. markdown2 在win10下无法预览解决方案

    今天升级完Win10发现心爱的markdownPad 2无法预览,显示the view has crashed! 按照官网的Q&A http://markdownpad.com/faq.htm ...

  10. Win8 +PHP+IIS配置

    1.安装IIS:控制面板-程序和功能-打开或关闭Windows功能 2.配置PHP环境 -添加ISAPI筛选: -添加脚本映射: