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网络编程(weekly summary1)
网络的目的是什么? 用于信息传输.接受 能把各个点.面.体的信息链接到一起 实现资源的共享 OSI模型: 应用层:提供程序服务 表示层:数据加密.优化.压缩 会话层: ...
- 孤荷凌寒自学python第四十四天Python操作 数据库之准备工作
孤荷凌寒自学python第四十四天Python操作数据库之准备工作 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) 今天非常激动地开始接触Python的数据库操作的学习了,数据库是系统化设计 ...
- crmsh语法
.查看配置信息 crm(live)# configure crm(live)configure# show node node1 node node2 property cib-bootstrap-o ...
- 1020 Tree Traversals (25 分)(二叉树的遍历)
给出一个棵二叉树的后序遍历和中序遍历,求二叉树的层序遍历 #include<bits/stdc++.h> using namespace std; ; int in[N]; int pos ...
- 软工实践Alpha冲刺(5/10)
队名:起床一起肝活队 组长博客:博客链接 作业博客:班级博客本次作业的链接 组员情况 组员1(队长):白晨曦 过去两天完成了哪些任务 描述: 已经解决登录注册等基本功能的界面. 完成了主界面的基本布局 ...
- Linux自学系列 -- 常用指令的使用
1.查看目录下内容>ls //列出目录下的文件信息>ls -l //以“详细信息"查看目录文件>ls -a //查看目录“全部”(包括隐藏文件)文件> ...
- J2EE的十三个技术——EJB之消息驱动JMS
JMS--Java Message Service JAVA的消息服务,消息可实现两端通信. 用于访问面向消息中间件的标准api,他提供与厂商无关的访问方法,以访问消息收发服务. 特点:即使其中一方不 ...
- 在LinkedIn的 Kafka 生态系统
在LinkedIn的 Kafka 生态系统 Apache Kafka是一个高度可扩展的消息传递系统,作为LinkedIn的中央数据管道起着至关重要的作用. Kafka 是在2010年在LinkedIn ...
- BZOJ3238 [Ahoi2013]差异 【后缀数组 + 单调栈】
题目链接 BZOJ3238 题解 简单题 经典后缀数组 + 单调栈套路,求所有后缀\(lcp\) #include<iostream> #include<cstdio> #in ...
- 《c程序设计语言》读书笔记-5.9-指针转换天数和日期
#include "stdio.h" #include "stdlib.h" #include "string.h" static char ...