题解:

题意:

输入n个DNA序列,你的任务是求出一个长度最大的字符串,使得它在超过一半的DNA序列中出现。如果有多解,按照字典序从小到大输入所有解。

把n个DNA序列拼在一起,中间用没有出现过的字符分割。然后求出height数组。

二分满足要求的字符串长度L,然后判断是否可行。

判断可行:

分组方法,如果某一组(段)有超过n/2的DNA串(是对应的输入的DNA串要有n/2个),则可行。

参考代码:

 #include<bits/stdc++.h>
using namespace std;
const int maxn=*+;
const int maxm=*;
int idx[maxm],n;
struct SuffixArray{
int s[maxm];
int sa[maxm],height[maxm],rank[maxm],n;
int t[maxm*],t2[maxm*];
long long cnt[maxm];
void clear(){n=;}
void build_sa(int m)
{
int i,*x=t,*y=t2;
for(i=;i<m;i++) cnt[i]=;
for(i=;i<n;i++) cnt[x[i]=s[i]]++;
for(i=;i<m;i++) cnt[i]+=cnt[i-];
for(i=n-;i>=;i--) sa[--cnt[x[i]]]=i;
for(int k=,p=;k<n;k <<=)
{
p=;
for(i=n-k;i<n;i++) y[p++]=i;
for(i=;i<n;i++) if(sa[i]>=k) y[p++]=sa[i]-k;
for(i=;i<m;i++) cnt[i]=;
for(i=;i<n;i++) cnt[x[y[i]]]++;
for(i=;i<m;i++) cnt[i]+=cnt[i-];
for(i=n-;i>=;i--) sa[--cnt[x[y[i]]]]=y[i];
swap(x,y);
p=;x[sa[]]=;
for(i=;i<n;i++)
{
if(y[sa[i-]]==y[sa[i]]&&y[sa[i-]+k]==y[sa[i]+k]) x[sa[i]]=p-;
else x[sa[i]]=p++;
}
if(p>=n) break;
m=p;
}
}
void build_height()
{
int k=;
for(int i=;i<n;i++) rank[sa[i]]=i;
for(int i=;i<n;i++)
{
if(k) k--;
if(!rank[i]) continue;
int j=sa[rank[i]-];
while(s[i+k]==s[j+k]) k++;
height[rank[i]]=k;
}
}
} SA; inline void add(int ch,int id)
{
idx[SA.n]=id;
SA.s[SA.n++]=ch;////
} int flag[maxn];
inline int check(int ans)
{
int check_clock=;
memset(flag,,sizeof(flag));
for(int i=;i<SA.n;i++)
{
if(SA.height[i]>=ans)
{
flag[idx[SA.sa[i]]]=check_clock;
flag[idx[SA.sa[i-]]]=check_clock;
}
else
{
int cnt=;
for(int j=;j<n;j++) if(flag[j]==check_clock) cnt++;
if(cnt>n/) return true;
flag[idx[SA.sa[i]]]=++check_clock;
}
}
return false;
} inline void print_ans(int l,int r)
{
for(int i=l;i<=r;i++) printf("%c",SA.s[i]+'a'-);
printf("\n");
} inline void print(int ans)
{
int check_clock=;
memset(flag,,sizeof(flag));
for(int i=;i<SA.n;i++)
{
if(SA.height[i]>=ans)
{
flag[idx[SA.sa[i]]]=check_clock;
flag[idx[SA.sa[i-]]]=check_clock;
}
else
{
int cnt=;
for(int j=;j<n;j++) if(flag[j]==check_clock) cnt++;
if(cnt>n/) print_ans(SA.sa[i-],SA.sa[i-]+ans-);
flag[idx[SA.sa[i]]]=++check_clock;
}
}
}
char s[+];
int kase=;
int main()
{
int maxlen;
while(scanf("%d",&n)==&&n)
{
if(kase++) printf("\n");
SA.clear();
maxlen=;
for(int i=;i<n;i++)
{
scanf("%s",s);
int l=strlen(s);
maxlen=max(maxlen,l);
for(int j=;j<l;j++) add(s[j]-'a'+,i);
add(+i,n);
}
if(n==) {printf("%s\n",s);continue;}
SA.build_sa(+n);
SA.build_height();
int l=,r=maxlen,ans=;
while(l<=r)
{
int mid=((l+r)>>);
if(check(mid)) ans=mid,l=mid+;
else r=mid-;
}
if(ans) print(ans);
else printf("?\n");
}
return ;
}

UVA-11107 Life Forms(求出现K次的子串,后缀数组+二分答案)的更多相关文章

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

                                                                              Life Forms Time Limit: 500 ...

  2. POJ 3294 Life Forms(后缀数组+二分答案)

    [题目链接] http://poj.org/problem?id=3294 [题目大意] 求出在至少在一半字符串中出现的最长子串. 如果有多个符合的答案,请按照字典序输出. [题解] 将所有的字符串通 ...

  3. poj 3294 Life Forms - 后缀数组 - 二分答案

    题目传送门 传送门I 传送门II 题目大意 给定$n$个串,询问所有出现在严格大于$\frac{n}{2}$个串的最长串.不存在输出'?' 用奇怪的字符把它们连接起来.然后求sa,hei,二分答案,按 ...

  4. ural1297 求最长回文子串 | 后缀数组

    #include<cstdio> #include<algorithm> #include<cstring> #define N 20005 using names ...

  5. POJ 3294 Life Forms 后缀数组+二分 求至少k个字符串中包含的最长子串

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

  6. uva 11107 Life Forms

    题意:给你N个串,求一个串在大于等于N/2的模板串中连续出现.如果有多解按字典序最小输出. 白书模板题.二分答案+合并模板串成一个新串,扫秒新串的height数组. 考查后缀数组+LCP #inclu ...

  7. POJ 3294 UVA 11107 Life Forms 后缀数组

    相同的题目,输出格式有区别. 给定n个字符串,求最长的子串,使得它同时出现在一半以上的串中. 不熟悉后缀数组的童鞋建议先去看一看如何用后缀数组计算两个字符串的最长公共子串 Ural1517 这道题的思 ...

  8. UVA - 11107 Life Forms (广义后缀自动机+后缀树/后缀数组+尺取)

    题意:给你n个字符串,求出在超过一半的字符串中出现的所有子串中最长的子串,按字典序输出. 这道题算是我的一个黑历史了吧,以前我的做法是对这n个字符串建广义后缀自动机,然后在自动机上dfs,交上去AC了 ...

  9. UVA 11107 Life Forms——(多字符串的最长公共子序列,后缀数组+LCP)

    题意: 输入n个序列,求出一个最大长度的字符串,使得它在超过一半的DNA序列中连续出现.如果有多解,按照字典序从小到大输出所有解. 分析:这道题的关键是将多个字符串连接成一个串,方法是用不同的分隔符把 ...

随机推荐

  1. MySQL-配置环境变量及修改密码(附-mysql安装教程)

    MySQL-配置环境变量和修改密码 mysql的安装教程:链接:https://pan.baidu.com/s/1rrPT2X0yRF58kN8jZZx-Mg 密码:55dh 一. 闪退问题 1.1. ...

  2. Flutter之环境配置与项目搭建

    Flutter之环境配置与项目搭建 一,介绍 1.1,Dart Dart 是一种 易于学习. 易于扩展.并且可以部署到 任何地方 的 应用 编程 语言.并且同时借鉴了Java和JavaScript.D ...

  3. [LC]111题 二叉树的最小深度 (递归)

    ①题目 给定一个二叉树,找出其最小深度. 最小深度是从根节点到最近叶子节点的最短路径上的节点数量. 说明: 叶子节点是指没有子节点的节点. 示例: 给定二叉树 [3,9,20,null,null,15 ...

  4. windows 激活工具链接

    链接:https://pan.baidu.com/s/1FphGFZhhLp01akGTDWjW2A  密码:f9t7

  5. nyoj 48-小明的调查作业(set)

    48-小明的调查作业 内存限制:64MB 时间限制:1000ms Special Judge: No accepted:15 submit:29 题目描述: 小明的老师布置了一份调查作业,小明想在学校 ...

  6. 力扣(LeetCode)从不订购的客户-数据库题 个人题解

    SQL架构 某网站包含两个表,Customers 表和 Orders 表.编写一个 SQL 查询,找出所有从不订购任何东西的客户. Customers 表: +----+-------+ | Id | ...

  7. list,tuple,dict,set 思维导图整理

  8. Winform-最大化窗口

    设置winform窗体最大化,填满整个屏幕 this.WindowState = FormWindowState.Maximized;

  9. AE安装部署以及监测ArcEngine runtime 9.3是否安装

    目的:用ArcEngine9.3开发项目以后,用Visual Studio2008打包工具打包: 同时监测别的机器上是否有ArcEngine Runtime或者Desktop的支持. 解决方案: 1. ...

  10. 实现自定义的参数解析器——HandlerMethodArgumentResolver

    1.为什么需要自己实现参数解析器 我们都知道在有注解的接口方法中加上@RequestBody等注解,springMVC会自动的将消息体等地方的里面参数解析映射到请求的方法参数中. 如果我们想要的信息不 ...