POJ3294 Life Forms(二分+后缀数组)
给n个字符串,求最长的多于n/2个字符串的公共子串。
依然是二分判定+height分组。
- 把这n个字符串连接,中间用不同字符隔开,跑后缀数组计算出height;
- 二分要求的子串长度,判断是否满足:height分组,统计一个组不同的字符串个数是否大于n/2;
- 最后输出方案,根据二分得出的子串长度的结果,直接再遍历一遍height,因为这儿是有序的后缀所以找到一个就直接输出。
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define MAXN 111000 int wa[MAXN],wb[MAXN],wv[MAXN],ws[MAXN];
int cmp(int *r,int a,int b,int l){
return r[a]==r[b] && r[a+l]==r[b+l];
}
int sa[MAXN],rank[MAXN],height[MAXN];
void SA(int *r,int n,int m){
int *x=wa,*y=wb; for(int i=; i<m; ++i) ws[i]=;
for(int i=; i<n; ++i) ++ws[x[i]=r[i]];
for(int i=; i<m; ++i) ws[i]+=ws[i-];
for(int i=n-; i>=; --i) sa[--ws[x[i]]]=i; int p=;
for(int j=; p<n; j<<=,m=p){
p=;
for(int i=n-j; i<n; ++i) y[p++]=i;
for(int i=; i<n; ++i) if(sa[i]>=j) y[p++]=sa[i]-j;
for(int i=; i<n; ++i) wv[i]=x[y[i]];
for(int i=; i<m; ++i) ws[i]=;
for(int i=; i<n; ++i) ++ws[wv[i]];
for(int i=; i<m; ++i) ws[i]+=ws[i-];
for(int i=n-; i>=; --i) sa[--ws[wv[i]]]=y[i];
swap(x,y); x[sa[]]=; p=;
for(int i=; i<n; ++i) x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p-:p++;
} for(int i=; i<n; ++i) rank[sa[i]]=i;
int k=;
for(int i=; i<n-; height[rank[i++]]=k){
if(k) --k;
for(int j=sa[rank[i]-]; r[i+k]==r[j+k]; ++k);
}
} int n,m,r[MAXN],belong[MAXN];
bool isok(int len){
int cnt=;
bool vis[]={};
for(int i=; i<=n; ++i){
if(height[i]>=len){
if(!vis[belong[sa[i]]]){
vis[belong[sa[i]]]=;
++cnt;
}
if(!vis[belong[sa[i-]]]){
vis[belong[sa[i-]]]=;
++cnt;
}
}else{
if(cnt>(m>>)) return ;
memset(vis,,sizeof(vis));
cnt=;
}
}
return ;
}
void pnt(int len){
int cnt=,idx;
bool vis[]={};
for(int i=; i<=n; ++i){
if(height[i]>=len){
idx=sa[i];
if(!vis[belong[sa[i]]]){
vis[belong[sa[i]]]=;
++cnt;
}
if(!vis[belong[sa[i-]]]){
vis[belong[sa[i-]]]=;
++cnt;
}
}else{
if(cnt>(m>>)){
for(int j=; j<len; ++j){
putchar(r[idx+j]+'a'-);
}
putchar('\n');
}
memset(vis,,sizeof(vis));
cnt=;
}
}
}
int main(){
char s[];
while(~scanf("%d",&m) && m){
n=;
for(int i=; i<m; ++i){
scanf("%s",s);
for(int j=; s[j]; ++j){
belong[n]=i;
r[n++]=s[j]-'a'+;
}
r[n++]=+i;
}
r[--n]=;
SA(r,n+,);
int l=,r=;
while(l<r){
int mid=l+r+>>;
if(isok(mid)) l=mid;
else r=mid-;
}
if(l==) puts("?");
else pnt(l);
putchar('\n');
}
return ;
}
POJ3294 Life Forms(二分+后缀数组)的更多相关文章
- 2018.11.28 poj3294 Life Forms(后缀数组+双指针)
传送门 后缀数组经典题目. 我们先把所有的字符串都接在一起. 然后求出hththt数组和sasasa数组. 然后对于sasasa数组跑双指针统计答案. 如果双指针包括进去的属于不同字符串的数量达到了题 ...
- poj3294 Life Forms(后缀数组)
[题目链接] http://poj.org/problem?id=3294 [题意] 多个字符串求出现超过R次的最长公共子串. [思路] 二分+划分height,判定一个组中是否包含不小于R个不同字符 ...
- POJ3294 Life Forms 【后缀数组】
生命形式 时间限制: 5000MS 内存限制: 65536K 提交总数: 16660 接受: 4910 描述 你可能想知道为什么大多数外星人的生命形式与人类相似,不同的是表面特征,如身高,肤色 ...
- BZOJ 2946 [Poi2000]公共串 (二分+Hash/二分+后缀数组/后缀自动机)
求多串的最长公共字串. 法1: 二分长度+hash 传送门 法2: 二分+后缀数组 传送门 法3: 后缀自动机 拿第一个串建自动机,然后用其他串在上面匹配.每次求出SAM上每个节点的最长匹配长度后,再 ...
- POJ 3294 Life Forms(后缀数组+二分答案)
[题目链接] http://poj.org/problem?id=3294 [题目大意] 求出在至少在一半字符串中出现的最长子串. 如果有多个符合的答案,请按照字典序输出. [题解] 将所有的字符串通 ...
- HDU4080 Stammering Aliens(二分 + 后缀数组)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=4080 Description Dr. Ellie Arroway has establish ...
- HDU5853 Jong Hyok and String(二分 + 后缀数组)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5853 Description Jong Hyok loves strings. One da ...
- 【HDU 5030】Rabbit's String (二分+后缀数组)
Rabbit's String Problem Description Long long ago, there lived a lot of rabbits in the forest. One d ...
- POJ-3294-Life Forms(后缀数组-不小于 k 个字符串中的最长子串)
题意: 给定 n 个字符串,求出现在不小于 k 个字符串中的最长子串. 分析: 将 n 个字符串连起来,中间用不相同的且没有出现在字符串中的字符隔开,求后缀数组. 然后二分答案,将后缀分成若干组,判断 ...
随机推荐
- Python调用Webservice
使用Python调用webservice 推荐使用 suds包 该包一般在Python2.x python3各种麻烦 略过 实例 import suds # webservice url url ...
- java jdbc与odbc数据库的连接mysql数据库
1.jdbc连接数据库要添加mysql-connector-java-5.1.38-bin.jar库 2.odbc连接数据库要添加odbc数据源 3.测试代码 DBHelper.java代码jdbc连 ...
- A. Vasya and Book
题目原址 http://codeforces.com/contest/1082/problem/A 题目内容 一共n页书,现在位于第x位,想要看第y页,每次只能翻d页,注意总能翻到第1页和第n页. V ...
- Unresolved defparam reference to 'read_aclr_synch' in dcfifo_component.read_aclr_synch
问题: 今天用 questasim 仿真出现下面这个问题. Unresolved defparam reference to 'read_aclr_synch' in dcfifo_component ...
- HDU 4763 Theme Section ( KMP next函数应用 )
设串为str, 串长为len. 对整个串求一遍next函数,从串结尾开始顺着next函数往前找<=len/3的最长串,假设串长为ans,由于next的性质,所以找到的串肯定满足E……E这种形式, ...
- 软工实践Alpha冲刺(6/10)
队名:起床一起肝活队 组长博客:博客链接 作业博客:班级博客本次作业的链接 组员情况 组员1(队长):白晨曦 过去两天完成了哪些任务 描述: 已经解决登录注册等基本功能的界面. 完成了主界面的基本布局 ...
- Comparable和Comparator的学习笔记
目录 Comparable和Comparator的实现 Comparable接口 Comparator接口 总结 参考自 今天在项目开发中,遇到要对List中的对象按照对象某一属性进行排序的问题,我发 ...
- ajax是可以本地运行的
ajax是可以本地运行的,经过验证,可以是可以,但跟浏览器有关,火狐和新IE可以,chrome不可以,旧ie不知道什么原因也不可以.但是浏览器也有它的安全策略,必须是同一目录下的文件可以访问.chro ...
- 【PHP】- 启用CRUL和GD
1.修改php.ini文件,确保extension_dir配置为php目录的ext,如图: 2.修改php.ini文件,将以下两项取消注释: 3.将php目录下的 libeay32.dll 和 lib ...
- Qt编程的一些技巧
1.Qt程序在运行过程中,调用函数(如lcdNumber->display(num))显示数据到界面上时,并不会马上刷新屏幕显示,而是要等主程序运行到函数a.exec()时,才刷新屏幕,如下 因 ...