后缀数组


  好感动,复习了下后缀数组居然写出来了……(感谢ykz大神)

  求最长公共子串……WA了一发是因为:【不同字符串之间要用不同的特殊字符隔开】否则就会匹配到相同→_→比如都是aaa结尾,如果用相同特殊字符就会使得最长公共子串变成aaa#这样子……

 /**************************************************************
Problem: 2946
User: Tunix
Language: C++
Result: Accepted
Time:60 ms
Memory:4104 kb
****************************************************************/ //BZOJ 2946
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
#define pb push_back
using namespace std;
typedef long long LL;
inline int getint(){
int r=,v=; char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-')r=-;
for(; isdigit(ch);ch=getchar()) v=v*+ch-'';
return r*v;
}
const int N=1e5+,INF=~0u>>;
/*******************template********************/
int sa[N],rank[N],height[N],belong[N],wa[N],wb[N],c[N],n,m;
int len[];
char s[N];
bool cmp(int *r,int a,int b,int l){
return r[a]==r[b] && r[a+l]==r[b+l];
}
void DA(char *s,int *sa,int n,int m){
int i,j,p,*x=wa,*y=wb;
rep(i,m) c[i]=;
rep(i,n) c[x[i]=s[i]]++;
F(i,,m-) c[i]+=c[i-];
D(i,n-,) sa[--c[x[i]]]=i;
for(j=,p=;p<n;j<<=,m=p){
for(p=,i=n-j;i<n;i++) y[p++]=i;
rep(i,n) if (sa[i]>=j) y[p++]=sa[i]-j; rep(i,m) c[i]=;
rep(i,n) c[x[y[i]]]++;
F(i,,m-) c[i]+=c[i-];
D(i,n-,) sa[--c[x[y[i]]]]=y[i];
swap(x,y); p=; x[sa[]]=;
F(i,,n-) x[sa[i]]=cmp(y,sa[i-],sa[i],j) ? p- : p++;
}
}
void calheight(char *s,int *sa,int n){
int k=;
F(i,,n) rank[sa[i]]=i;
rep(i,n){
if (k) k--;
int j=sa[rank[i]-];
while(s[i+k]==s[j+k]) k++;
height[rank[i]]=k;
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("2946.in","r",stdin);
freopen("2946.out","w",stdout);
#endif
n=getint();int l=;
F(i,,n){
scanf("%s",s+l);
len[i]=strlen(s)-l;
l=strlen(s);
s[l++]='a'-n+i;
}
rep(i,l) s[i]=s[i]-'a'+;
l--;
DA(s,sa,l+,);
calheight(s,sa,l);
int tmp=;
rep(i,l){
if (s[i]<) {tmp++;continue;}
belong[rank[i]]=tmp;
} bool vis[]={};
int L=,R=,mid,cnt,ans=;
while(L<=R){
mid=(L+R)>>;bool sign=;
cnt=; memset(vis,,sizeof vis);
F(i,n,l){
if (height[i]<mid){
cnt=;memset(vis,,sizeof vis);
vis[belong[i]]=; continue;
}
if (!vis[belong[i]]) vis[belong[i]]=,cnt++;
if (cnt==n) sign=;
}
if (sign) ans=mid,L=mid+;
else R=mid-;
}
printf("%d\n",ans);
return ;
}

2946: [Poi2000]公共串

Time Limit: 3 Sec  Memory Limit: 128 MB
Submit: 160  Solved: 67
[Submit][Status][Discuss]

Description

 
       给出几个由小写字母构成的单词,求它们最长的公共子串的长度。
任务:
l        读入单词
l        计算最长公共子串的长度
l        输出结果
 

Input

 
文件的第一行是整数 n,1<=n<=5,表示单词的数量。接下来n行每行一个单词,只由小写字母组成,单词的长度至少为1,最大为2000。
 

Output

仅一行,一个整数,最长公共子串的长度。
 

Sample Input

3
abcb
bca
acbc

Sample Output

HINT

Source

[Submit][Status][Discuss]

【BZOJ】【2946】【POI2000】公共串的更多相关文章

  1. BZOJ 2946: [Poi2000]公共串

    2946: [Poi2000]公共串 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 787  Solved: 342[Submit][Status][D ...

  2. BZOJ 2946: [Poi2000]公共串( 后缀自动机 )

    一个串建后缀自动机, 其他串在上面跑, 然后用当前串跑的去更新全部 ------------------------------------------------------------------ ...

  3. bzoj 2946 [Poi2000]公共串——后缀自动机

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2946 对每个串都建一个后缀自动机,然后 dfs 其中一个自动机,记录同步的话在别的自动机上走 ...

  4. BZOJ 2946 [Poi2000]公共串 (二分+Hash/二分+后缀数组/后缀自动机)

    求多串的最长公共字串. 法1: 二分长度+hash 传送门 法2: 二分+后缀数组 传送门 法3: 后缀自动机 拿第一个串建自动机,然后用其他串在上面匹配.每次求出SAM上每个节点的最长匹配长度后,再 ...

  5. BZOJ 2946 POI2000 公共串 后缀自动机(多串最长公共子串)

    题意概述:给出N个字符串,每个串的长度<=2000(雾...可能是当年的年代太久远机子太差了),问这N个字符串的最长公共子串长度为多少.(N<=5) 抛开数据结构,先想想朴素做法. 设计一 ...

  6. BZOJ 2946 [Poi2000]公共串 ——后缀自动机

    任意选择一个串作为模式串,构建出后缀自动机. 然后用其他的串在后缀自动机上跑匹配. 然后就到了理解后缀自动机性质的时候. 在某一个节点的最大值是可以沿着parent树上传的. 然后用dp[i][j]表 ...

  7. bzoj 2946: [Poi2000]公共串【SAM】

    对第一个串建SAM,把剩下的串在上面跑,每次跑一个串的时候在SAM的端点上记录匹配到这的最大长度,然后对这些串跑的结果取min,然后从这些节点的min中取max就是答案 注意在一个点更新后它的祖先也会 ...

  8. 【BZOJ 2946】 2946: [Poi2000]公共串 (SAM)

    2946: [Poi2000]公共串 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 1063  Solved: 469 Description      ...

  9. 【BZOJ】2946: [Poi2000]公共串

    http://www.lydsy.com/JudgeOnline/problem.php?id=2946 题意:给n个串,求最大公共子串.(1<=n<=5,每个串长度<=2000) ...

  10. BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案

    BZOJ_2946_[Poi2000]公共串_后缀数组+二分答案 Description          给出几个由小写字母构成的单词,求它们最长的公共子串的长度. 任务: l        读入单 ...

随机推荐

  1. linux添加桌面快捷方式

    linux通过软件中心安装的程序快捷图标都放在/usr/share/applications/目录下.点选一个图标右键,选择复制到,目录选择桌面即可.    但是有一些软件自行安装后,在那个目录里没有 ...

  2. jenkins定时构建

    打开job的配置界面,在构建触发器栏下有Poll SCM(定时检查源码变更并构建)和Build periodically(周期进行项目构建,不关心源码是否变更) 定时构建语法: * * * * *(和 ...

  3. 005 Hadoop的三种模式区别

    1.本地模式 -默认模式. -不对配置文件进行修改. -使用本地文件系统,而不是分布式文件系统. -Hadoop不会启动NameNode.DataNode.ResourceManager.NodeMa ...

  4. git获取帮助

    想了解 Git 的各式工具该怎么用,可以阅读它们的使用帮助,方法有三: $ git help <verb> $ git <verb> --help $ man git-< ...

  5. 「长乐集训 2017 Day10」划分序列 (二分 dp)

    「长乐集训 2017 Day10」划分序列 题目描述 给定一个长度为 n nn 的序列 Ai A_iA​i​​,现在要求把这个序列分成恰好 K KK 段,(每一段是一个连续子序列,且每个元素恰好属于一 ...

  6. iOS系统中导航栏的转场解决方案与最佳实践

    背景 目前,开源社区和业界内已经存在一些 iOS 导航栏转场的解决方案,但对于历史包袱沉重的美团 App 而言,这些解决方案并不完美.有的方案不能满足复杂的页面跳转场景,有的方案迁移成本较大,为此我们 ...

  7. 【SQL】182. Duplicate Emails

    Write a SQL query to find all duplicate emails in a table named Person. +----+---------+ | Id | Emai ...

  8. [ 原创 ] Java基础5--abstract class和interface的区别

    1.含有abstract抽象修饰符的类就是抽象类.abstract 类不能创建实例对象 2.含有abstract方法的类必须定义为abstract class,abstract class类中的方法不 ...

  9. 洛谷.4252.[NOI2006]聪明的导游(提答 直径 随机化)

    题目链接 随机化 暴力: 随便从一个点开始DFS,每次从之前得到的f[i]最大的子节点开始DFS.f[i]为从i开始(之前)能得到的最大答案. 要注意的是f[i]应当有机会从更小的答案更新, 9.10 ...

  10. 周末 “CTO训练营”

    今天下午去中关村参加了51cto高招 “CTO训练营”  第一期. 呃蛮有收获,聊技术发展,技术cto线路或对应发展,人事对应cto发展,投资人对应看法,51cto老总的看法. 呃,挺有意思,同样认识 ...