POJ - 2774 Long Long Message (后缀数组/后缀自动机模板题)
后缀数组:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
typedef long long ll;
const int N=2e5+,mod=;
char s[N];
int sa[N],buf1[N],buf2[N],c[N],n,n1,n2,rnk[N],ht[N],ST[N][],Log[N];
void Sort(int* x,int* y,int m) {
for(int i=; i<m; ++i)c[i]=;
for(int i=; i<n; ++i)++c[x[i]];
for(int i=; i<m; ++i)c[i]+=c[i-];
for(int i=n-; i>=; --i)sa[--c[x[y[i]]]]=y[i];
}
void da(char* s,int n,int m=) {
int *x=buf1,*y=buf2;
x[n]=y[n]=-;
for(int i=; i<n; ++i)x[i]=s[i],y[i]=i;
Sort(x,y,m);
for(int k=; k<n; k<<=) {
int p=;
for(int i=n-k; i<n; ++i)y[p++]=i;
for(int i=; i<n; ++i)if(sa[i]>=k)y[p++]=sa[i]-k;
Sort(x,y,m),p=,y[sa[]]=;
for(int i=; i<n; ++i)y[sa[i]]=x[sa[i-]]==x[sa[i]]&&x[sa[i-]+k]==x[sa[i]+k]?p-:p++;
if(p==n)break;
swap(x,y),m=p;
}
}
void getht() {
for(int i=; i<n; ++i)rnk[sa[i]]=i;
ht[]=;
for(int i=,k=; i<n; ++i) {
if(k)--k;
if(!rnk[i])continue;
for(; s[i+k]==s[sa[rnk[i]-]+k]; ++k);
ht[rnk[i]]=k;
}
}
void initST() {
for(int i=; i<n; ++i)ST[i][]=ht[i];
for(int j=; (<<j)<=n; ++j)
for(int i=; i+(<<j)-<n; ++i)
ST[i][j]=min(ST[i][j-],ST[i+(<<(j-))][j-]);
}
int lcp(int l,int r) {
if(l==r)return n-sa[l];
if(l>r)swap(l,r);
l++;
int k=Log[r-l+];
return min(ST[l][k],ST[r-(<<k)+][k]);
}
int main() {
Log[]=-;
for(int i=; i<N; ++i)Log[i]=Log[i>>]+;
scanf("%s",s),n1=strlen(s),s[n1]='|',scanf("%s",s+n1+),n=strlen(s);
da(s,n),getht(),initST();
vector<int> v1,v2;
for(int i=; i<n1; ++i)v1.push_back(rnk[i]);
for(int i=n1+; i<n; ++i)v2.push_back(rnk[i]);
sort(v1.begin(),v1.end());
sort(v2.begin(),v2.end());
int ans=;
for(int i=,j=; i<v1.size(); ++i) {
for(; j<v2.size()&&v2[j]<v1[i]; ++j);
if(j->=)ans=max(ans,lcp(v1[i],v2[j-]));
if(j<v2.size())ans=max(ans,lcp(v1[i],v2[j]));
}
printf("%d\n",ans);
return ;
}
后缀自动机:
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=2e5+,M=,mod=;
char s[N];
int n,fa[N],go[N][M],mxl[N],last,tot;
int newnode(int l) {int u=++tot; mxl[u]=l,memset(go[u],,sizeof go[u]); return u;}
void add(int ch) {
int p=last,np=last=newnode(mxl[p]+);
for(; ~p&&!go[p][ch]; p=fa[p])go[p][ch]=np;
if(!~p)fa[np]=;
else {
int q=go[p][ch];
if(mxl[q]==mxl[p]+)fa[np]=q;
else {
int nq=newnode(mxl[p]+);
memcpy(go[nq],go[q],sizeof go[q]);
fa[nq]=fa[q],fa[q]=fa[np]=nq;
for(; ~p&&go[p][ch]==q; p=fa[p])go[p][ch]=nq;
}
}
}
int main() {
fa[]=-;
scanf("%s",s),n=strlen(s);
for(int i=; i<n; ++i)add(s[i]-'a');
scanf("%s",s),n=strlen(s);
int ans=;
for(int i=,u=,l=; i<n; ++i) {
int ch=s[i]-'a';
if(!go[u][ch]) {
for(; u&&!go[u][ch]; u=fa[u]);
l=mxl[u];
}
if(go[u][ch])u=go[u][ch],++l;
ans=max(ans,l);
}
printf("%d\n",ans);
return ;
}
POJ - 2774 Long Long Message (后缀数组/后缀自动机模板题)的更多相关文章
- (17/34)AC自动机/后缀数组/后缀自动机(施工中)
		
快补题别再摸鱼了(17/34) 1.AC自动机 #define maxnode 1000010 #define maxsize 26 struct ahocT{ int ch[maxnode][max ...
 - 字符串的模板 Manacher kmp ac自动机 后缀数组 后缀自动机
		
为何scanf("%s", str)不需要&运算 经常忘掉的字符串知识点,最好不加&,不加&最标准,指针如果像scanf里一样加&是错的,大概是未定 ...
 - 【整理】如何选取后缀数组&&后缀自动机
		
后缀家族已知成员 后缀树 后缀数组 后缀自动机 后缀仙人掌 后缀预言 后缀Splay ? 后缀树是后缀数 ...
 - loj6173 Samjia和矩阵(后缀数组/后缀自动机)
		
题目: https://loj.ac/problem/6173 分析: 考虑枚举宽度w,然后把宽度压位集中,将它们哈希 (这是w=2的时候) 然后可以写一下string=“ac#bc” 然后就是求这个 ...
 - 牛客网 桂林电子科技大学第三届ACM程序设计竞赛 A.串串-后缀自动机模板题
		
链接:https://ac.nowcoder.com/acm/contest/558/A来源:牛客网 A.串串 小猫在研究字符串. 小猫在研究字串. 给定一个长度为N的字符串S,问所有它的子串Sl…r ...
 - POJ 2774  Long Long Message 后缀数组
		
Long Long Message Description The little cat is majoring in physics in the capital of Byterland. A ...
 - poj 2774 Long Long Message 后缀数组基础题
		
Time Limit: 4000MS Memory Limit: 131072K Total Submissions: 24756 Accepted: 10130 Case Time Limi ...
 - 后缀数组(模板题) - 求最长公共子串 - poj 2774 Long Long Message
		
Language: Default Long Long Message Time Limit: 4000MS Memory Limit: 131072K Total Submissions: 21 ...
 - [POJ 2774] Long Long Message 【后缀数组】
		
题目链接:POJ - 2774 题目分析 题目要求求出两个字符串的最长公共子串,使用后缀数组求解会十分容易. 将两个字符串用特殊字符隔开再连接到一起,求出后缀数组. 可以看出,最长公共子串就是两个字符 ...
 - POJ 2774 Long Long Message(后缀数组)
		
[题目链接] http://poj.org/problem?id=2774 [题目大意] 求最长公共子串 [题解] 将两个串中间嵌一个字符相连,求一遍后缀数组 如果排名相邻的两个后缀的开端是分属于两个 ...
 
随机推荐
- Python-数据库连表查询、子查询
			
连表查询 [实例]通过例子来熟悉连表查询的概念 # 第一步:建表 # 建立英雄职业分类表格 create table classification( id int, name varchar(20) ...
 - 【Python开发】Url中文字符时记得转码edcode("utf-8")
			
在url中使用中文其实是一个坏习惯,会带来一系列的转码问题, 我更喜欢英文译名或者id来标识某个uri.但是现实往往是残酷的, 特别是在我们调用别人服务时候,有时候被逼无奈使用中文URL. Pytho ...
 - Angular中引入外部js的使用方式
			
在Angular中我们或许会用到部分外部插件的时候,像Bootstrap,Jquery这些当然我们可以通过Npm安装包的形式引入,但是还有一些其它的js库需要引入的话,我们又应该怎样操作呢? 在这里做 ...
 - 【转帖】msvcp100.dll和msvcr100.dll
			
VS发布软件时去除msvcp100.dll和msvcr100.dll图解说明 https://blog.csdn.net/yu__jia/article/details/82753262 msvcp. ...
 - 小菜鸟之java内存结构
			
JVM启动流程: JVM基本结构图: <深入理解Java虚拟机(第二版)>中的描述是下面这个样子的: Java中的内存分配: Java程序在运行时,需要在内存中的分配空间.为了提高运算效率 ...
 - ssl安全验证
			
#ssl验证 r=requests.get('https://www.12306.cn',verify=False) print(r.content.decode('utf-8')) 结果:
 - # jsp及servlet学习笔记
			
目录 jsp及servlet学习笔记 JSP(Java Server Page Java服务端网页) 指令和动作: servlet(小服务程序) jsp及servlet学习笔记 JSP(Java Se ...
 - Two strings CodeForces - 762C (字符串,双指针)
			
大意: 给定字符串$a$,$b$, $b$可以任选一段连续的区间删除, 要求最后$b$是$a$的子序列, 求最少删除区间长度. 删除一段连续区间, 那么剩余的一定是一段前缀和后缀. 判断是否是子序列可 ...
 - redis 学习(5)-- 列表类型
			
redis 学习(5)-- 列表类型 列表特点 有序.可以重复.左右两边插入弹出 索引相关知识 索引从左往右,从0开始逐个增大 0 1 2 3 4 5 索引从右往左,从-1开始逐个减小 -6 -5 - ...
 - 剑指offer-构建乘积数组-数组-python
			
题目描述 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1].不 ...