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个字符串中最长公共子串】后缀数组的更多相关文章

  1. POJ3294--Life Forms 后缀数组+二分答案 大于k个字符串的最长公共子串

                                                                              Life Forms Time Limit: 500 ...

  2. 【Java例题】5.5 两个字符串中最长公共子串

    5. 查找两个字符串中含有的最长字符数的公共子串. package chapter5; import java.util.Scanner; public class demo5 { public st ...

  3. POJ-3294-Life Forms(后缀数组-不小于 k 个字符串中的最长子串)

    题意: 给定 n 个字符串,求出现在不小于 k 个字符串中的最长子串. 分析: 将 n 个字符串连起来,中间用不相同的且没有出现在字符串中的字符隔开,求后缀数组. 然后二分答案,将后缀分成若干组,判断 ...

  4. 字符串中连续出现最多的子串 &amp; 字符串中最长反复子串

    字符串中连续出现最多的子串 & 字符串中最长反复子串 字符串中连续出现最多的子串 & 字符串中最长反复子串,这两个问题都能够用后缀数组来表示,至于后缀数组能够參考编程珠玑P156:后缀 ...

  5. POJ2774 Long Long Message —— 后缀数组 两字符串的最长公共子串

    题目链接:https://vjudge.net/problem/POJ-2774 Long Long Message Time Limit: 4000MS   Memory Limit: 131072 ...

  6. 求两个字符串的最长公共子串——Java实现

    要求:求两个字符串的最长公共子串,如“abcdefg”和“adefgwgeweg”的最长公共子串为“defg”(子串必须是连续的) public class Main03{ // 求解两个字符号的最长 ...

  7. poj 2774 后缀数组 两个字符串的最长公共子串

    Long Long Message Time Limit: 4000MS   Memory Limit: 131072K Total Submissions: 31904   Accepted: 12 ...

  8. poj2774 后缀数组2个字符串的最长公共子串

    Long Long Message Time Limit: 4000MS   Memory Limit: 131072K Total Submissions: 26601   Accepted: 10 ...

  9. [URAL-1517][求两个字符串的最长公共子串]

    Freedom of Choice URAL - 1517 Background Before Albanian people could bear with the freedom of speec ...

随机推荐

  1. php简易实现计划任务

    index.php <?php function ceshi(){ $wan = file_get_contents('./wangt_index.txt',true); $jifen = $w ...

  2. ExtJs工具篇(2)——Aptana Studio 3 汉化

    本身用的是中文版本的,但是输入一些中文后,竟然有乱码,所以就想把它汉化.在网上搜索了一下,把步骤记录如下: 首先到这个网站去 http://aptana.com/support 选择View Docu ...

  3. 一个知乎日报pwa

    前几天写了一篇文章关于如何实现一个简单版的pwa应用,端午撸了一个简易版知乎日报pwa. 关于如何写一个pwa,这里就不多介绍了,请移步这里.应用使用vue+vuex+axios,API这里,这里做了 ...

  4. 【Swift】日期比较函数 记录下 Comparing date in Swift

    Add this code to your project and comparing dates is easier than ever 扩展NSDATE //swift 3.0.2 extensi ...

  5. python 基础篇 14 程程器表达式 内置函数

    昨日内容回顾    可迭代对象:        内部含有__iter__方法的就是可迭代对象.        可迭代对象不能取值,因为内部不含有__next__方法.     可迭代对象 ---> ...

  6. KVM WEB管理工具——WebVirtMgr(二)日常配置

    配置宿主机 1.登录WebVirtMgr管理平台 2.添加宿主机 选择首页的WebVirtMgr -->Addd Connection 选择“SSH链接“,设置Label,IP,用户 注意:La ...

  7. python第一天(安装运行python)

    1. 安装Python 3.7 目前,Python有两个版本,一个是2.x版,一个是3.x版,这两个版本是不兼容的.由于3.x版越来越普及,我们的教程将以最新的Python 3.7版本为基础.请确保你 ...

  8. C++STL——set

    一.相关定义 set 集合,有唯一性,即每一个元素只有一个: 是一个有序的容器,里面的元素都是排序好的: 支持插入,删除,查找等操作. 注意 set中的元素可以是任意类型的,但是由于需要排序,所以元素 ...

  9. C#数据库连接问题

    最近在看C#,今天下午刚开始接触C#的数据库连接,SQL Server2008,问题如图:在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误.未找到或无法访问服务器.请验证实例名 ...

  10. lintcode-57-三数之和

    57-三数之和 给出一个有n个整数的数组S,在S中找到三个整数a, b, c,找到所有使得a + b + c = 0的三元组. 注意事项 在三元组(a, b, c),要求a <= b <= ...