【poj3294-不小于k个字符串中最长公共子串】后缀数组

1.注意每两个串之间的连接符要不一样。
2.分组的时候要注意最后一组啊!又漏了!
3.开数组要考虑连接符的数量。100010是不够的至少要101000。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
using namespace std; const int N=;
int n,cl,sl,ans,tt,c[N],tl[N],tr[N],al[N],ar[N],rk[N],Rs[N],sa[N],wr[N],y[N],h[N],st[N],ed[N];
char s[];
bool vis[]; int minn(int x,int y){return x<y ? x:y;} void get_sa(int m)
{
for(int i=;i<=cl;i++) rk[i]=c[i];
for(int i=;i<=m;i++) Rs[i]=;
for(int i=;i<=cl;i++) Rs[rk[i]]++;
for(int i=;i<=m;i++) Rs[i]+=Rs[i-];
for(int i=cl;i>=;i--) sa[Rs[rk[i]]--]=i; int ln=,p=;
while(p<cl)
{
int k=;
for(int i=cl-ln+;i<=cl;i++) y[++k]=i;
for(int i=;i<=cl;i++) if(sa[i]>ln) y[++k]=sa[i]-ln; for(int i=;i<=cl;i++) wr[i]=rk[y[i]];
for(int i=;i<=m;i++) Rs[i]=;
for(int i=;i<=cl;i++) Rs[wr[i]]++;
for(int i=;i<=m;i++) Rs[i]+=Rs[i-];
for(int i=cl;i>=;i--) sa[Rs[wr[i]]--]=y[i]; for(int i=;i<=cl;i++) wr[i]=rk[i];
for(int i=cl+;i<=cl+ln;i++) wr[i]=;
p=;rk[sa[]]=;
for(int i=;i<=cl;i++)
{
if(wr[sa[i]]!=wr[sa[i-]] || wr[sa[i]+ln]!=wr[sa[i-]+ln]) p++;
rk[sa[i]]=p;
}
ln*=,m=p;
}
sa[]=,rk[]=;
} void get_h()
{
int k=,j;
for(int i=;i<=cl;i++) if(rk[i]!=)
{
j=sa[rk[i]-];
if(k) k--;
while(c[j+k]==c[i+k] && j+k<=cl && i+k<=cl) k++;
h[rk[i]]=k;
}
h[]=;
}
int idx(int x)
{
for(int i=;i<=n;i++)
if(st[i]<=x && x<=ed[i]) return i;
return ;
} bool check(int k)
{
memset(vis,,sizeof(vis));
int now=cl;
tt=;
for(int i=;i<=cl;i++)
{
if(h[i]<k)
{
int cnt=;
for(int j=;j<=n;j++) if(vis[j]) cnt++;
if(cnt>(n/)) tl[++tt]=sa[i-],tr[tt]=tl[tt]+now-;
memset(vis,,sizeof(vis));
now=cl-sa[i]+;vis[idx(sa[i])]=;
}
else
{
now=minn(now,h[i]);
vis[idx(sa[i])]=;
}
}
int cnt=;
for(int j=;j<=n;j++) if(vis[j]) cnt++;
if(cnt>(n/)) tl[++tt]=sa[cl-],tr[tt]=tl[tt]+now-;
if(tt) return ;
return ;
} int main()
{
freopen("a.in","r",stdin);
int T=;
while()
{
T++;
scanf("%d",&n);
if(n==) return ;
cl=;ans=;
for(int i=;i<=n;i++)
{
scanf("%s",s+);
sl=strlen(s+);
if(i>) c[++cl]=i;
st[i]=cl+;
for(int j=;j<=sl;j++) c[++cl]=s[j];
ed[i]=cl;
}
if(n==) {printf("%c\n",c[]);continue;}
get_sa();
get_h();
// for(int i=1;i<=cl;i++) printf("%c",c[i]);printf("\n");
// for(int i=1;i<=cl;i++) printf("%d ",sa[i]);printf("\n");
// for(int i=1;i<=cl;i++) printf("%d ",rk[i]);printf("\n");
// for(int i=1;i<=cl;i++) printf("%d ",h[i]);printf("\n");
int l=,r=cl,mid;
while(l<r)
{
mid=(l+r+)/;
if(check(mid))
{
l=mid;
ans=tt;
for(int i=;i<=tt;i++) al[i]=tl[i],ar[i]=tr[i];
}
else r=mid-;
}
if(T>) printf("\n");
if(ans)
{
for(int i=;i<=ans;i++)
{
for(int j=al[i];j<=ar[i];j++) printf("%c",c[j]);
printf("\n");
}
}
else printf("?\n");
}
return ;
}
【poj3294-不小于k个字符串中最长公共子串】后缀数组的更多相关文章
- POJ3294--Life Forms 后缀数组+二分答案 大于k个字符串的最长公共子串
Life Forms Time Limit: 500 ...
- 【Java例题】5.5 两个字符串中最长公共子串
5. 查找两个字符串中含有的最长字符数的公共子串. package chapter5; import java.util.Scanner; public class demo5 { public st ...
- POJ-3294-Life Forms(后缀数组-不小于 k 个字符串中的最长子串)
题意: 给定 n 个字符串,求出现在不小于 k 个字符串中的最长子串. 分析: 将 n 个字符串连起来,中间用不相同的且没有出现在字符串中的字符隔开,求后缀数组. 然后二分答案,将后缀分成若干组,判断 ...
- 字符串中连续出现最多的子串 & 字符串中最长反复子串
字符串中连续出现最多的子串 & 字符串中最长反复子串 字符串中连续出现最多的子串 & 字符串中最长反复子串,这两个问题都能够用后缀数组来表示,至于后缀数组能够參考编程珠玑P156:后缀 ...
- POJ2774 Long Long Message —— 后缀数组 两字符串的最长公共子串
题目链接:https://vjudge.net/problem/POJ-2774 Long Long Message Time Limit: 4000MS Memory Limit: 131072 ...
- 求两个字符串的最长公共子串——Java实现
要求:求两个字符串的最长公共子串,如“abcdefg”和“adefgwgeweg”的最长公共子串为“defg”(子串必须是连续的) public class Main03{ // 求解两个字符号的最长 ...
- poj 2774 后缀数组 两个字符串的最长公共子串
Long Long Message Time Limit: 4000MS Memory Limit: 131072K Total Submissions: 31904 Accepted: 12 ...
- poj2774 后缀数组2个字符串的最长公共子串
Long Long Message Time Limit: 4000MS Memory Limit: 131072K Total Submissions: 26601 Accepted: 10 ...
- [URAL-1517][求两个字符串的最长公共子串]
Freedom of Choice URAL - 1517 Background Before Albanian people could bear with the freedom of speec ...
随机推荐
- 开源版本 hadoop-2.7.5 + apache-hive-2.1.1 + spark-2.3.0-bin-hadoop2.7整合使用
一,开源软件版本: hadoop版本 : hadoop-2.7.5 hive版本 :apache-hive-2.1.1 spark版本: spark-2.3.0-bin-hadoop2.7 各个版本到 ...
- 台湾ML笔记--1.2 formalize the learning probelm
Basic notations input: x∈χ (customer application) output: y∈y (good/bad after approving cred ...
- 问题:调用 ASP.Net Core WebAPI的HTTP POST方法时,从 [FromBody] 中读取的 MongoDB GeoJsonObjectModel成员总是null
问题描述: POST/PUT to ASP.Net Core with [FromBody] to a MongoDB GeoJsonObjectModel member is always null ...
- C++重载赋值操作符
1.C++中重载赋值操作函数应该返回什么? 类重载赋值操作符一般都是作为成员函数而存在的,那函数应该返回什么类型呢?参考内置类型的赋值操作,例如 int x,y,z; x=y=z=15; 赋值行为相当 ...
- 教你如何用Docker快速搭建深度学习环境
本教程搭建集 Tensorflow.Keras.Coffe.PyTorch 等深度学习框架于一身的环境,及jupyter. 本教程使用nvidia-docker启动实例,通过本教程可以从一个全新的Ub ...
- Linux SPI总线和设备驱动架构之二:SPI通用接口层
通过上一篇文章的介绍,我们知道,SPI通用接口层用于把具体SPI设备的协议驱动和SPI控制器驱动联接在一起,通用接口层除了为协议驱动和控制器驱动提供一系列的标准接口API,同时还为这些接口API定义了 ...
- akka与slf4j导致jvm直接crash的诡异
流程很简单,创建actorSystem,通过actorSystem获取AkkaQueryServiceRetriever,进而通过传递path获得的Gateway进行通信. 之前在主项目里跑的很稳定, ...
- ashx文件和aspx
ashx文件和aspx文件有什么不同? 我们先新建一个ashx文件看看: <%@ WebHandler Language="C#" Class="Handler&q ...
- GET传值
发送页: <form id="form1" runat="server"> <div> <asp:TextBox ID=</ ...
- [Leetcode] merge sorted array 合并数组
Given two sorted integer arrays A and B, merge B into A as one sorted array. Note: You may assume th ...