后缀数组三·重复旋律3
#1415 : 后缀数组三·重复旋律3
时间限制:5000ms
单点时限:1000ms
内存限制:256MB
描述
小Hi平时的一大兴趣爱好就是演奏钢琴。我们知道一个音乐旋律被表示为长度为 N 的数构成的数列。小Hi在练习过很多曲子以后发现很多作品中的旋律有共同的部分。
旋律是一段连续的数列,如果同一段旋律在作品A和作品B中同时出现过,这段旋律就是A和B共同的部分,比如在abab 在 bababab 和 cabacababc 中都出现过。小Hi想知道两部作品的共同旋律最长是多少?
输入
共两行。一行一个仅包含小写字母的字符串。字符串长度不超过 100000。
输出
一行一个整数,表示答案。
- 样例输入
-
abcdefg abacabca
- 样例输出
-
3
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #include<queue> #include<cmath> #include <bits/stdc++.h> #include<vector> typedef long long ll; const int maxn=2e6+6; using namespace std; typedef std::pair<ll,ll> pll; typedef std::string str; int sa[maxn],rk[maxn],tp[maxn],height[maxn]; char s1[maxn],s2[maxn]; int ton[maxn],e[maxn],mx,n; inline void rsort(){ for(register int i=0;i<mx;++i)ton[i]=0; for(register int i=1;i<=n;++i)ton[rk[i]]++; for(register int i=1;i<=mx;++i)ton[i]=ton[i]+ton[i-1]; for(register int i=n;i>=1;--i)sa[ton[rk[tp[i]]]--]=tp[i]; } inline void solve(){ for(register int i=1;i<=n;++i)rk[i]=e[i],tp[i]=i; rsort(); for(register int w=1,p=0;w<=n&&p<n;w*=2,mx=p){ p=0; for(register int i=n-w+1;i<=n;++i){ tp[++p]=i; } for(register int i=1;i<=n;++i){ if(sa[i]>w){ tp[++p]=sa[i]-w; } } rsort(); swap(rk,tp); rk[sa[1]]=p=1; for(register int i=2;i<=n;++i){ rk[sa[i]]=(tp[sa[i-1]]==tp[sa[i]]&&tp[sa[i-1]+w]==tp[sa[i]+w])?p:++p; } if(p>=n)break; } int k=0; for(register int i=1;i<=n;++i){ rk[sa[i]]=i; } for(register int i=1;i<=n;++i){ if(k)k--; else k=0; int j=sa[rk[i]-1]; while(e[i+k]==e[j+k])++k; height[rk[i]]=k; } } int main() { //freopen("1.txt","r",stdin); scanf("%s%s",s1+1,s2+1); int len1=strlen(s1+1),len2=strlen(s2+1); n=len1+len2+1; for(register int i=1;i<=len1;++i){ e[i]=s1[i]-'a'+1; mx=max(mx,e[i]); } for(register int i=1;i<=len2;++i){ e[i+len1+1]=s2[i]-'a'+1; mx=max(mx,e[i+len1+1]); } e[len1+1]=300; mx=max(mx,300); solve(); int res=0; // for(register int i=1;i<=n;++i){ // printf("debug rk[%d] = %d sa[%d] = %d height[%d] = %d\n",i,rk[i],i,sa[i],i,height[i]); // } for(register int i=2;i<=n;++i){ if(sa[i]<=len1&&sa[i-1]<=len1)continue; if(sa[i]>len1&&sa[i-1]>len1)continue; res=max(res,height[i]); } printf("%d\n",res); return 0; } /* * abcdefg abacabca */
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 解答了困扰我五年的技术问题
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· 用 C# 插值字符串处理器写一个 sscanf
· Java 中堆内存和栈内存上的数据分布和特点
· 开发中对象命名的一点思考
· 为什么说在企业级应用开发中,后端往往是效率杀手?
· DeepSeek 解答了困扰我五年的技术问题。时代确实变了!
· 本地部署DeepSeek后,没有好看的交互界面怎么行!
· 趁着过年的时候手搓了一个低代码框架
· 推荐一个DeepSeek 大模型的免费 API 项目!兼容OpenAI接口!