POJ 3294 二分找超过一半字符串中存在的子串
题目大意:
给定n个字符串,求出现在不小于k/2个字符串中的最长子串。
二分找对应子串长度的答案,将所有字符串链接成一个长字符串求后缀数组,记录每一个位置本属于第几个字符串,利用height查询的时候,
根据记录的位置不断判断是否出现重复的字符串是在同一个字符串内的
#include <cstdio>
#include <cstring>
#include <vector>
#include <iostream>
using namespace std;
typedef long long ll;
const int N = ;
int r[N] , sa[N] , rank[N] , height[N];
int K , wa[N] , wb[N] , wv[N] , wsf[N];
int cmp(int *r , int a , int b , int l){return r[a]==r[b]&&r[a+l]==r[b+l];}
void da(int *r , int *sa , int n , int m)
{
int i,j,p,*x=wa,*y=wb,*t;
for(i=;i<m;i++)wsf[i]=;
for(i=;i<n;i++)wsf[x[i]=r[i]]++;
for(i= ; i<m ; i++) wsf[i]+=wsf[i-];
for(i=n-;i>=;i--) sa[--wsf[x[i]]]=i;
for(j=,p=;p<n;j*=,m=p){
for(p=,i=n-j;i<n;i++) y[p++]=i;
for(i=;i<n;i++) if(sa[i]>=j)y[p++]=sa[i]-j;
for(i=;i<n;i++) wv[i]=x[y[i]];
for(i=;i<m;i++) wsf[i]=;
for(i=;i<n;i++) wsf[wv[i]]++;
for(i=;i<m;i++) wsf[i]+=wsf[i-];
for(i=n-;i>=;i--) sa[--wsf[wv[i]]]=y[i];
for(t=x,x=y,y=t,p=,x[sa[]]=,i=;i<n;i++)
x[sa[i]]=cmp(y,sa[i-],sa[i],j)?p-:p++;
}
return;
}
void callHeight(int *r , int *sa , int n)
{
int i,j,k=;
for(i=;i<=n;i++) rank[sa[i]]=i;
for(i=;i<n;height[rank[i++]]=k)
for(k?k--:,j=sa[rank[i]-];r[i+k]==r[j+k];k++);
return;
}
#define ll long long
int n , len , pos[][] , dif , mp[N];
bool vis[];
char s[][] , all[N];
vector<int> ans , tmp;
bool check(int mid)
{
tmp.clear();
bool flag = false;
memset(vis , , sizeof(vis));
int cnt = , rec = sa[];
vis[sa[]] = true;
for(int i= ; i<len ; i++){
if(height[i]<mid){
if(cnt>n/){
tmp.push_back(rec);
flag = true;
}
memset(vis , , sizeof(vis));
cnt = , vis[mp[sa[i]]] = true , rec = sa[i];
}
else{
if(!vis[mp[sa[i]]]){
vis[mp[sa[i]]] = true;
cnt++;
rec = sa[i];
}
}
}
if(flag) ans = tmp;
return flag;
}
int bin_search()
{
int l= , r= , ans= , mid;
while(l<=r){
mid = (l+r)>>;
if(check(mid)) l=mid+ , ans=mid;
else r=mid-;
}
return ans;
}
int main()
{
// freopen("a.in" , "r" , stdin);
bool flag = false;
while(scanf("%d" , &n) , n){
if(flag) puts("");
flag = true;
len = , dif = ;
for(int i= ; i<n ; i++){
scanf("%s" , s[i]);
for(int j= ; j<strlen(s[i]) ; j++) all[len] = s[i][j] , mp[len]=i+ , r[len++] = s[i][j]-'a'+;
pos[i][] = len;
all[len] = '*';
mp[len]=i+ , r[len++] = dif++;
}
r[len-] = ;
da(r , sa , len , dif);
// for(int i=0 ; i<len ; i++) cout<<"i: "<<i<<" "<<sa[i]<<endl;
callHeight(r , sa , len-);
int ret = bin_search();
if(!ret) puts("?");
else{
for(int i= ; i<ans.size() ; i++){
for(int j=ans[i] , t= ; t<ret ; j++ , t++) printf("%c" , all[j]);
puts("");
}
}
}
}
POJ 3294 二分找超过一半字符串中存在的子串的更多相关文章
- poj 3294 后缀数组 多字符串中不小于 k 个字符串中的最长子串
Life Forms Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 16223 Accepted: 4763 Descr ...
- 剑指Offer 找出字符串中第一个只出现一次的字符
题目描述 找出字符串中第一个只出现一次的字符 如果无此字符 请输出'.' 输入描述: 输入一串字符,由小写字母组成 输出描述: 输出一个字符 输入例子: asdfasdfo 输出例子: o 思路:数组 ...
- 找出字符串中第一个不重复的字符(JavaScript实现)
如题~ 此算法仅供参考,小菜基本不懂高深的算法,只能用最朴实的思想去表达. //找出字符串中第一个不重复的字符 // firstUniqueChar("vdctdvc"); --& ...
- HDU 4622 求解区间字符串中的不同子串的个数
题目大意: 给定一个长度<2000的串,再给最多可达10000的询问区间,求解区间字符串中的不同子串的个数 这里先考虑求解一整个字符串的所有不同子串的方法 对于后缀自动机来说,我们动态往里添加一 ...
- 【Java】获取两个字符串中最大相同子串
题目 获取两个字符串中最大相同子串 前提 两个字符串中只有一个最大相同子串 解决方案 public class StringDemo { public static void main(String[ ...
- [LeetCode] Find All Anagrams in a String 找出字符串中所有的变位词
Given a string s and a non-empty string p, find all the start indices of p's anagrams in s. Strings ...
- 【easy】438.Find All Anagrams in a String 找出字符串中所有的变位词
Input: s: "abab" p: "ab" Output: [0, 1, 2] Explanation: The substring with start ...
- js常会问的问题:找出字符串中出现次数最多的字符。
一.循环obj let testStr = 'asdasddsfdsfadsfdghdadsdfdgdasd'; function getMax(str) { let obj = {}; for(le ...
- 【SQLSERVER】如何找出字符串中的数字
可以通过写自定义函数实现,以下提供两种思路来解决: 1.通过正则匹配,找到字符串中的数字,一个一个拼起来 /*方法一: 一个一个找出来*/ CREATE FUNCTION [dbo].[Fun_Get ...
随机推荐
- UIScrollView(滚动视图)
(1)常用属性: 1)@property(nonatomic)CGPointcontentOffset; 这个属性⽤用来表⽰示UIScrollView滚动的位置 2)@property(nonatom ...
- 从C++到GO
从C++到GO 刚开始接触Go语言,看了两本Go语言的书,从c++开发者的角度来看看go语言的新特性,说下自己感触较深的几点: 并发编程 Go语言层面支持协程,将并发业务逻辑从异步转为同步,大幅提高开 ...
- Openstack+Kubernetes+Docker微服务实践之路--Docker和Registry2
渐入佳境,我们开始比较具体的工作,由于Docker是一个基础组件,所以本文的主题是Docker和Registry2. 底层系统基于Centos7,先在一台云主机上安装Docker,Docker的安装非 ...
- T-Sql 递归查询(给定节点查所有父节点、所有子节点的方法)
-- 查找所有父节点with tab as( select Type_Id,ParentId,Type_Name from Sys_ParamType_V2_0 where Type_Id=316-- ...
- 个人博客作业Week2
一.是否需要有代码规范 这些规范都是官僚制度下产生的浪费大家的编程时间.影响人们开发效率, 浪费时间的东西. 我反驳这个观点,这些规范是成千上万的程序员在开发程序中总结出来的代码规范,他有助于我们的开 ...
- css3——新盒子定义box-sizing
css3对盒子有了新定义,以前的 盒子实际宽(高) = padding + width(height) + ( border * 2); 使用了box-sizing之后盒子实际宽(高) 就等于 wid ...
- spring cloud资料
https://segmentfault.com/a/1190000006216281 http://git.oschina.net/zhou666/spring-cloud-7simple zuul ...
- Hangfire项目使用
基本介绍: hangfire 主要用于根据设置时间来执行任务,间隔几分钟执行一次,每天几点钟执行一次,如此执行任务. 方法: backgroundjob.enqueue(()=>"要执 ...
- PageObject小结
写之前想把这次的灵感记录下来: 之前看PO模式几次,始终不得法,感觉一片混乱,可就在一天早上,正在照着别人的代码写自己项目时突然脑海中想通了几个问题:1.为什么要封装页面.2.各个模块的作用以及为什么 ...
- SQL Server 2012 联机丛书离线安装
昨日根据微软官网的方式安装SQL Server 2012 联机丛书报错,无法安装: 联机丛书下载位置及安装方式: 按照给出的方式安装,无法完成,错误如下: