【模板】后缀数组

#include<cstdio> #include<algorithm> #include<cstring> #include<cmath> //Accepted??? using namespace std; const int N=2e5+5; const int Maxchar=26; char s[N],a[N]; int n,m,nn,num,x[N],y[N],c[N],sa[N]; int h[N],height[N],rk[N]; int f[N][20],res; void solve() { m=Maxchar; for(int i=1;i<=n;i++) c[x[i]=s[i]-'a'+1]++; for(int i=2;i<=m;i++) c[i]+=c[i-1]; for(int i=n;i>=1;i--) sa[c[x[i]]--]=i; for(int k=1;k<=n;k<<=1) { num=0; for(int i=n-k+1;i<=n;i++) y[++num]=i; for(int i=1;i<=n;i++) if(sa[i]>k) y[++num]=sa[i]-k; for(int i=1;i<=m;i++) c[i]=0; for(int i=1;i<=n;i++) c[x[i]]++; for(int i=2;i<=m;i++) c[i]+=c[i-1]; for(int i=n;i>=1;i--) sa[c[x[y[i]]]--]=y[i]; for(int i=1;i<=n;i++) y[i]=x[i],x[i]=0; x[sa[1]]=1;num=1; for(int i=2;i<=n;i++) x[sa[i]]=(y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k])?num:++num; if(m==n) break; m=num; } } void solve2() { int k=0; for (int i=1; i<=n; ++i) rk[sa[i]]=i; for (int i=1; i<=n; ++i) { if (rk[i]==1) continue;//第一名height为0 if (k) --k;//h[i]>=h[i-1]-1; int j=sa[rk[i]-1]; while (j+k<=n && i+k<=n && s[i+k]==s[j+k]) ++k; height[rk[i]]=k;//h[i]=height[rk[i]]; } for(int i=1;i<=n;i++) f[i][0]=height[i]; for(int j=1;j<20;j++) { for(int i=1;i<=n-(1<<j)+1;i++) { f[i][j]=min(f[i][j-1],f[i+(1<<(j-1))][j-1]); } } } int ask(int x,int y) { int k=int(log(1.0*(y-x+1))/log(2.0)); return min(f[x][k],f[y-(1<<k)+1][k]); } void solve3() { int k1=0,k2=0; for(int i=1;i<=n;i++) { // printf("%d ",sa[i]); if(sa[i]<=nn) { if(k2) res=max(res,ask(k2+1,i)); k1=i; } else { if(k1) res=max(res,ask(k1+1,i)); k2=i; } } } //思路:求出两个数的后缀数组,然后按字典序排序. //根据LCP的性质,a,b的lcp为[a,b]中height的最小值,那么枚举a串,找到距离最近的b串求lcp的贡献即可. int main() { memset(f,0x3f,sizeof(f)); scanf("%s",s+1); n=strlen(s+1); nn=n; scanf("%s",a+1); int len=strlen(a+1); for(int i=1;i<=len;i++) s[n+i]=a[i]; n+=len; solve(); solve2(); solve3(); printf("%d",res); }

__EOF__

本文作者仰望星空的蚂蚁
本文链接https://www.cnblogs.com/cqbzly/p/17530366.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   仰望星空的蚂蚁  阅读(8)  评论(0编辑  收藏  举报  
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
点击右上角即可分享
微信分享提示