把字符串S的所有后缀按照字典序排列,排名为 i 的后缀记为SA[ i ]
额外地,我们考虑排名为 i 的后缀与排名为 i-1 的后缀,把二者的最长公共前缀的长度记为 hgt[i]
使用快排、Hash 与二分 求出 两个数组
#include<iostream> #include <algorithm> #include <cstring> using namespace std; #define ll unsigned long long const int N=1e6+5; char s[N]; int id[N],n; ll h[N],pow[N]; ll bas=131; ll f1(int l,int r){ return h[r]-h[l-1]*pow[r-l+1]; } int find(int a,int b){ int l=0,r=n-max(a,b)+1; int t=0; while(l<=r){ int md=(l+r)/2; if(f1(a,a+md-1)==f1(b,b+md-1)) l=md+1,t=md; else r=md-1; } return t; } int cmp(int i,int j){ int k=find(i,j); int t1,t2; if(i+k<=n) t1=s[i+k]; else t1=-1e9; if(j+k<=n) t2=s[j+k]; else t2=-1e9; return t1<t2; } void sov(){ h[0]=0; int i,ans=0; n=strlen(s+1); for(i=1;i<=n;i++){ h[i]=h[i-1]*bas+s[i]; id[i]=i; } sort(id+1,id+1+n,cmp); for(i=1;i<=n;i++) cout<<id[i]-1<<' '; cout<<endl<<0; for(i=2;i<=n;i++) cout<<' '<<find(id[i],id[i-1]); cout<<endl; } main(){ int i; pow[0]=1; for(i=1;i<=1e6;i++) pow[i]=pow[i-1]*bas; cin>>s+1; sov(); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!