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 ...
随机推荐
- jsp获取服务端的访问信息
获取服务端访问信息 public static String getUrl(HttpServletRequest request){ String url = ""; if(req ...
- asp.net 使用IHttpModule 做权限检查 登录超时检查(转)
IHttpModule 权限 检查 登录超时检查 这样就不需要每个页面都做一次检查 也不需要继承任何父类. using System;using System.Collections.Generic; ...
- gulp 前端自动化工具
一开篇 在前端开发的过程中,我们经常会碰到压缩.合并.图片script 等,于是就有了gulp 前端自动化构建工具,它能帮你在前端开发中,节省时间. 1,安装 node.js 因为gulp 构建工具是 ...
- struts -执行流程
When a client request is given, a web container will receive request Web container loads web.xml and ...
- How to hanganalyze and systemstate dumps
Oracle support request hang analysis and system state dumps when rasing SR. One 10.1 or higher versi ...
- O-C相关04:类方法的概述与定义和调用
类方法的概述与定义和调用 1, 类方法的概述 类方法(class method)在其他编程语言中常常称为静态方法(例如 Java 或 C# 等). 与实例方法不同的是,类方法只需要使用类名即可调用, ...
- MVC5学习笔记
买了一本MVC5的书:ASP.NET MVC 5 高级编程(第5版).边学边记录一下 1.快速创建模型类,如:自动实现的属性 {get;set;} 输入“prop",按Tab两次,默认属性值 ...
- Javascript中bind()方法的使用与实现
对于bind,我愣了下,这个方法常用在jquery中,用于为被选元素添加一个或多个事件处理程序. 查了下手册,发现bind的作用和apply,call类似都是改变函数的execute context, ...
- YZOI Easy Round 2_化简(simplify.c/cpp/pas)
Description 给定一个多项式,输出其化简后的结果. Input 一个字符串,只含有关于字母x 的多项式,不含括号与分式,没有多余的空格. Output 一个字符串,化简后的多项式,按照次数从 ...
- fedora安装sublime text教程
下载 http://pan.baidu.com/s/1eRkEegM 解压 终端中切换到下载文件的目录下,执行以下命令: sudo tar -jxvf sublime_text_3_build_308 ...