POJ 1226 Substrings(后缀数组+二分答案)
【题目链接】 http://poj.org/problem?id=1226
【题目大意】
求在每个给出字符串中出现的最长子串的长度,字符串在出现的时候可以是倒置的。
【题解】
我们将每个字符串倒置,用拼接符和原串拼接,然后将所有通过这种方式得到的字符串拼接,做后缀数组,因为求最长子串,所以我们考虑二分答案后检验,将单串的拼接串视为一个串,我们在检验时只要判断是否在每个串中出现过即可。
【代码】
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
const int N=200010;
int n,m,rank[N],sa[N],h[N],tmp[N],cnt[N],ans,a[N],s[N]; char str[N];
void suffixarray(int n,int m){
int i,j,k;n++;
for(i=0;i<2*n+5;i++)rank[i]=sa[i]=h[i]=tmp[i]=0;
for(i=0;i<m;i++)cnt[i]=0;
for(i=0;i<n;i++)cnt[rank[i]=s[i]]++;
for(i=1;i<m;i++)cnt[i]+=cnt[i-1];
for(i=0;i<n;i++)sa[--cnt[rank[i]]]=i;
for(k=1;k<=n;k<<=1){
for(i=0;i<n;i++){
j=sa[i]-k;
if(j<0)j+=n;
tmp[cnt[rank[j]]++]=j;
}sa[tmp[cnt[0]=0]]=j=0;
for(i=1;i<n;i++){
if(rank[tmp[i]]!=rank[tmp[i-1]]||rank[tmp[i]+k]!=rank[tmp[i-1]+k])cnt[++j]=i;
sa[tmp[i]]=j;
}memcpy(rank,sa,n*sizeof(int));
memcpy(sa,tmp,n*sizeof(int));
if(j>=n-1)break;
}for(j=rank[h[i=k=0]=0];i<n-1;i++,k++)
while(~k&&s[i]!=s[sa[j-1]+k])h[j]=k--,j=rank[sa[j]+1];
}int len[N],u,K;
vector<int> S[N];
bool vis[N];
bool check(int L){
int cur=-1;
for(int i=1;i<=u;i++){
if(h[i]<L)S[++cur].clear();
S[cur].push_back(i);
}
for(int i=0;i<=cur;i++){
if(S[i].size()>=n){
memset(vis,0,sizeof(vis));
for(int j=0;j<S[i].size();j++){
int k=S[i][j];
int x=upper_bound(a,a+n+1,sa[k])-a-1;
vis[x]=1;
}int count=0;
for(int j=0;j<n;j++)if(vis[j])count++;
if(count>=n)return 1;
}
}return 0;
}int T;
int main(){
scanf("%d",&T);
while(T--){
scanf("%d",&n);
int tmp=200; u=0;
for(int i=0;i<n;i++){
scanf("%s",str);
len[i]=strlen(str);
for(int j=0;j<len[i];j++)s[u++]=(int)str[j];
s[u++]=tmp++;
for(int j=len[i]-1;j>=0;j--)s[u++]=(int)str[j];
s[u++]=tmp++;
}tmp=0; s[u]=0;
for(int i=0;i<=n;i++){
a[i]=tmp;
if(i<n)tmp=tmp+(i==0?2*len[i]+1:2*len[i]+2);
}suffixarray(u,410);
int l=1,r=100,ans=0;
while(l<=r){
int mid=(l+r)>>1;
if(check(mid))ans=mid,l=mid+1;
else r=mid-1;
}if(n==1)printf("%d\n",len[0]);
else printf("%d\n",ans);
}return 0;
}
POJ 1226 Substrings(后缀数组+二分答案)的更多相关文章
- poj 3415 Common Substrings - 后缀数组 - 二分答案 - 单调栈
题目传送门 传送点I 传送点II 题目大意 给定串$A, B$,求$A$和$B$长度大于等于$k$的公共子串的数量. 根据常用套路,用一个奇怪的字符把$A$,$B$连接起来,然后二分答案,然后按mid ...
- POJ - 1226 Substrings (后缀数组)
传送门:POJ - 1226 这个题跟POJ - 3294 和POJ - 3450 都是一样的思路,一种题型. POJ - 3294的题解可以见:https://www.cnblogs.com/li ...
- Poj 1743 Musical Theme(后缀数组+二分答案)
Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 28435 Accepted: 9604 Descri ...
- Poj 3261 Milk Patterns(后缀数组+二分答案)
Milk Patterns Case Time Limit: 2000MS Description Farmer John has noticed that the quality of milk g ...
- BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案
BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案 Description 给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l 读入单 ...
- POJ 3261 Milk Patterns(后缀数组+二分答案)
[题目链接] http://poj.org/problem?id=3261 [题目大意] 求最长可允许重叠的出现次数不小于k的子串. [题解] 对原串做一遍后缀数组,二分子串长度x,将前缀相同长度超过 ...
- POJ 3294 Life Forms(后缀数组+二分答案)
[题目链接] http://poj.org/problem?id=3294 [题目大意] 求出在至少在一半字符串中出现的最长子串. 如果有多个符合的答案,请按照字典序输出. [题解] 将所有的字符串通 ...
- POJ 1743 Musical Theme(后缀数组+二分答案)
[题目链接] http://poj.org/problem?id=1743 [题目大意] 给出一首曲子的曲谱,上面的音符用不大于88的数字表示, 现在请你确定它主旋律的长度,主旋律指的是出现超过一次, ...
- POJ 3080 Blue Jeans(后缀数组+二分答案)
[题目链接] http://poj.org/problem?id=3080 [题目大意] 求k个串的最长公共子串,如果存在多个则输出字典序最小,如果长度小于3则判断查找失败. [题解] 将所有字符串通 ...
随机推荐
- [poco] HttpRequest之post方法
转自 http://www.cnblogs.com/yuanxiaoping_21cn_com/archive/2012/06/10/2544032.html #import <iostream ...
- MYSQL定时创建表分区
MYSQL定时创建表分区 一.存储过程-表分区-----------------------------------------------------------------需求: 每月创建一个分区 ...
- jquery结合highcharts插件显示实时数据动态曲线图
效果如图所示: js代码如下: $(document).ready(function() { Highcharts.setOptions({ global: { useUTC: false }, co ...
- 环境配置与JBoss安装-EJB3.0入门经典学习笔记(1)
目录 1. JDK的安装 2. JBoss的安装 3. JBoss安装目录说明 1. JDK的安装 1) 下载JDK 下载地址:http://www.oracle.com/technetwork/ja ...
- php配置redis支持
在php.ini里面添加下面两行,注意这两行的顺序一定不要颠倒(扩展库下载网址https://github.com/phpredis/phpredis/downloads),同时注意这2个文件的版本一 ...
- Silverlight并行下载与串行下载
思路清晰后仅仅只需百来行代码便可轻松编写出一套完整的资源动态下载组件- SerialDownloader和ParallelDownloader,它们共用一个完成资源表,且串行下载集成了优先机制(Dow ...
- QT进度条QProgressBar的练习
progressbar.h #ifndef PROGRESSBAR_H #define PROGRESSBAR_H #include <QProgressBar> class QStrin ...
- 开源ceph管理平台inkscope部署手册
一.前情提要 关于inkscope就不做过多介绍了,就是ceph的一个开源管理控制平台,跟ceph官方的calamary以及intel的VSM差不多一类,只是各自侧重点不一样. 相对而言,因为inks ...
- C#中var关键字【转】
[转]http://blog.csdn.net/courageously/article/details/5695626 var关键字是C# 3.0开始新增的特性,称为推断类型 . 可以赋予局部变量推 ...
- select2插件常用方法汇总
1.获取下拉框的value和text <input type="hidden" name="xa" id="xa" data-plac ...