2018.11.30 spoj220 Relevant Phrases of Annihilation(后缀数组+二分答案)
传送门
代码:
先用特殊字符把所有字符串连接在一起。
然后二分答案将sasasa数组分组。
讨论是否存在一个组满足组内对于每一个字符串都存在两段不相交字串满足条件。
#include<bits/stdc++.h>
#define ri register int
using namespace std;
const int N=2e5+5;
int n,m,rk[N],ht[N],sa[N],sa2[N],len[N],st[N][18],Log[N],T_T,tt,mx[N],mn[N],idx[N];
char s[N],t[10005];
inline void Sort(){
static int cnt[N];
for(ri i=1;i<=m;++i)cnt[i]=0;
for(ri i=1;i<=n;++i)++cnt[rk[i]];
for(ri i=2;i<=m;++i)cnt[i]+=cnt[i-1];
for(ri i=n;i;--i)sa[cnt[rk[sa2[i]]]--]=sa2[i];
}
inline void getsa(){
for(ri i=1;i<=n;++i)rk[i]=(int)s[i],sa2[i]=i;
m=122,Sort();
for(ri w=1,p=0;m^n;w<<=1,p=0){
for(ri i=n-w+1;i<=n;++i)sa2[++p]=i;
for(ri i=1;i<=n;++i)if(sa[i]>w)sa2[++p]=sa[i]-w;
Sort(),swap(sa2,rk),rk[sa[1]]=p=1;
for(ri i=2;i<=n;++i)rk[sa[i]]=(sa2[sa[i]]==sa2[sa[i-1]]&&sa2[sa[i]+w]==sa2[sa[i-1]+w])?p:++p;
m=p;
}
for(ri i=1,j,k=0;i<=n;ht[rk[i++]]=k)for(k?--k:k,j=sa[rk[i]-1];s[i+k]==s[j+k];++k);
for(ri i=1;i<=n;++i)st[i][0]=ht[i];
for(ri j=1;j<=17;++j)for(ri i=1;i+(1<<j)<=n;++i)st[i][j]=min(st[i][j-1],st[i+(1<<(j-1))][j-1]);
}
inline int rmq(int l,int r){return min(st[l][Log[r-l+1]],st[r-(1<<Log[r-l+1])+1][Log[r-l+1]]);}
inline bool solve(int l,int r,int mid){
for(ri i=1;i<=tt;++i)mx[i]=-0x3f3f3f3f,mn[i]=0x3f3f3f3f;
for(ri i=l;i<=r;++i)mx[idx[sa[i]]]=max(mx[idx[sa[i]]],len[idx[sa[i]]]-sa[i]+1),mn[idx[sa[i]]]=min(mn[idx[sa[i]]],len[idx[sa[i]]]-sa[i]+1);
for(ri i=1;i<=tt;++i)if(mx[i]-mn[i]<mid)return 0;
return 1;
}
inline bool check(int mid){
for(ri l=1,r=1;l<=n;l=r+1){
while(ht[l]<mid&&l<=n)++l;
if(l>n)break;
r=l;
while(ht[r+1]>=mid&&r<n)++r;
if(solve(l-1,r,mid))return 1;
}
return 0;
}
int main(){
freopen("lx.in","r",stdin);
Log[0]=-1;
for(ri i=1;i<=200000;++i)Log[i]=Log[i>>1]+1;
scanf("%d",&T_T);
while(T_T--){
scanf("%d",&tt),n=0;
for(ri i=1;i<=tt;++i){
scanf("%s",t+1),s[++n]=(char)i,len[i]=strlen(t+1);
for(ri j=1;j<=len[i];++j)s[++n]=t[j];
len[i]+=len[i-1]+1;
}
for(ri i=1;i<=tt;++i)for(ri j=len[i-1]+1;j<=len[i];++j)idx[j]=i;
getsa();
int l=1,r=len[1],ans=0;
while(l<=r){
int mid=l+r>>1;
if(check(mid))ans=mid,l=mid+1;
else r=mid-1;
}
cout<<ans<<'\n';
}
return 0;
}
2018.11.30 spoj220 Relevant Phrases of Annihilation(后缀数组+二分答案)的更多相关文章
- SPOJ220 Relevant Phrases of Annihilation(后缀数组)
引用罗穗骞论文中的话: 先将n 个字符串连起来,中间用不相同的且没有出现在字符串中的字符隔开,求后缀数组.然后二分答案,再将后缀分组.判断的时候,要看是否有一组后缀在每个原来的字符串中至少出现两次,并 ...
- SPOJ - PHRASES Relevant Phrases of Annihilation —— 后缀数组 出现于所有字符串中两次且不重叠的最长公共子串
题目链接:https://vjudge.net/problem/SPOJ-PHRASES PHRASES - Relevant Phrases of Annihilation no tags You ...
- SPOJ220 Relevant Phrases of Annihilation
http://www.spoj.com/problems/PHRASES/ 题意:给n个串,求n个串里面都有2个不重叠的最长的字串长度. 思路:二分答案,然后就可以嘿嘿嘿 PS:辣鸡题目毁我青春,一开 ...
- SPOJ 220 Relevant Phrases of Annihilation(后缀数组+二分答案)
[题目链接] http://www.spoj.pl/problems/PHRASES/ [题目大意] 求在每个字符串中出现至少两次的最长的子串 [题解] 注意到这么几个关键点:最长,至少两次,每个字符 ...
- 2018.11.24 spoj New Distinct Substrings(后缀数组)
传送门 双倍经验(弱化版本) 考虑求出来heightheightheight数组之后用增量法. 也就是考虑每增加一个heightheightheight对答案产生的贡献. 算出来是∑∣S∣−heigh ...
- SPOJ - PHRASES K - Relevant Phrases of Annihilation
K - Relevant Phrases of Annihilation 题目大意:给你 n 个串,问你最长的在每个字符串中出现两次且不重叠的子串的长度. 思路:二分长度,然后将height分块,看是 ...
- POJ - 3294~Relevant Phrases of Annihilation SPOJ - PHRASES~Substrings POJ - 1226~POJ - 3450 ~ POJ - 3080 (后缀数组求解多个串的公共字串问题)
多个字符串的相关问题 这类问题的一个常用做法是,先将所有的字符串连接起来, 然后求后缀数组 和 height 数组,再利用 height 数组进行求解. 这中间可能需要二分答案. POJ - 3294 ...
- SPOJ - PHRASES Relevant Phrases of Annihilation
传送门:SPOJ - PHRASES(后缀数组+二分) 题意:给你n个字符串,找出一个最长的子串,他必须在每次字符串中都出现至少两次. 题解:被自己蠢哭...记录一下自己憨憨的操作,还一度质疑评测鸡( ...
- 【SPOJ 220】Relevant Phrases of Annihilation
http://www.spoj.com/problems/PHRASES/ 求出后缀数组然后二分. 因为有多组数据,所以倍增求后缀数组时要特判是否越界. 二分答案时的判断要注意优化! 时间复杂度\(O ...
随机推荐
- Application的特点
1.生命周期长.(内存泄漏) 2.单实例(一个进程就只有一个Application的实例对象) 3.onCreate的方法,可以认为一个应用程序的入口,做一些初始化的事情 4.不能自己new出 App ...
- 二叉树,B树,B+树,红黑树 简介
什么是二叉树? 在计算机科学中,二叉树是每个节点最多有两个子树的树结构.通常子树被称作“左子树”和“右子树”,左子树和右子树同时也是二叉树.二叉树的子树有左右之分,并且次序不能任意颠倒.二叉树是递归定 ...
- Codeforces Beta Round #63 (Div. 2)
Codeforces Beta Round #63 (Div. 2) http://codeforces.com/contest/69 A #include<bits/stdc++.h> ...
- P3375 【模板】KMP字符串匹配
P3375 [模板]KMP字符串匹配 https://www.luogu.org/problemnew/show/P3375 题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在 ...
- SpringBoot使用@Value从yml文件取值为空--注入静态变量
SpringBoot使用@Value从yml文件取值为空--注入静态变量 1.application.yml中配置内容如下: pcacmgr: publicCertFilePath: ...
- 快速排序中BUG int 与 int *
#include <iostream>using namespace std;int QKPass(int* , int , int); //若声明为 int QKPass(int, i ...
- 国内淘宝镜像 cnpm转npm
npm install -g cnpm --registry=http://registry.npm.taobao.org
- supervisor 使用教程(转)
原文地址:https://word.gw1770df.cc/2016-08-04/linux/supervisor-%E4%BD%BF%E7%94%A8%E6%95%99%E7%A8%8B/ Supe ...
- POI依据类型设置导出格式
//设置Bigdecimal数据导出时以数值形式输出 CellStyle decimalStyle = workbook.createCellStyle(); DataFormat decimalDf ...
- YII2中如何自定义全局函数
有些时候我们需要自定义一些全局函数来完成我们的工作. 方法一: 直接写在入口文件处 <?php // comment out the following two lines when deplo ...