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则判断查找失败. [题解] 将所有字符串通 ...
随机推荐
- Python进阶之返回函数
返回函数 .note-content {font-family: "Helvetica Neue",Arial,"Hiragino Sans GB"," ...
- [剖析Javascript原理]1.原生数据类型
一.原生数据类型 JS共有5种原生数据类型: Boolean true或者false String 字符串,在单引号或者双引号之间(不存在字符类型) Number 整数或者浮点数 Null 空 und ...
- HTML豆ちしき
HTML文档里所有的空白符(空格,Tab,换行,回车)会被浏览器忽略,唯一的例外是空格,对空格的处理方式是所有连续的空格被当成一个空格,不管有一个,还是两个,还是100个.之所以有这样的规则是因为忽略 ...
- Activity之间定时跳转
起源:很多应用在打开时,首先会加载欢迎页面,经过几秒后再跳转到主页面. 下面,我通过两种不同的方式来实现页面的定时跳转. 第一种方式: 通过Timer类的schedule方法. 实现从MainActi ...
- 移动跨平台开发框架Ionic开发一个新闻阅读APP
移动跨平台开发框架Ionic开发一个新闻阅读APP 前言 这是一个系列文章,从环境搭建开始讲解,包括网络数据请求,将持续更新到项目完结.实战开发中遇到的各种问题的解决方案,也都将毫无保留的分享给大家. ...
- 16.java.lang.InterruptedException
java.lang.InterruptedException 被中止异常 当某个线程处于长时间的等待.休眠或其他暂停状态,而此时其他的线程通过Thread的interrupt方法终止该线程时抛出该异常 ...
- Oracle EBS-SQL (AR-1):检查应收收款发生额
SELECT SUM(nvl(dist.amount_dr,0))-SUM(nvl(dist.amount_cr,0)) FROM ar_cash_receipt_history_all hist, ...
- Codeforces 263E
Codeforces 263E 原题 题目描述:一个\(n \times m\)的矩阵,每格有一个数,给出一个整数\(k\),定义函数\(f(x, y)\): \[f(x, y)=\sum_{i=1} ...
- uestc Palindromic String
字符串hash因为如果一个字符串是回文串,那么正着做哈希和反着做哈希结果应该一样.于是我们先正反各做一边哈希.如果判断出来一个字符串是回文穿那么这个字符串的前半部分和后半部分的重数一定相同,于是当前位 ...
- Android 模拟系统事件(三)
简介 Android系统是基于Linux内核的,而Linux内核继承和兼容了丰富的Unix系统进程间通信(IPC)机制.Binder其实也不是Android提出来的一套新的进程间通信机制,它是基于Op ...