https://www.luogu.org/problemnew/show/P3809
分析
SA模板(找个时间把SA学习笔记写了)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int N=1e6+10; int n,m; int c[N],x[N],y[N],sa[N],rk[N],height[N]; char s[N]; void SA() { memset(c,0,sizeof c); for (int i=1;i<=n;i++) c[x[i]=s[i]]++; for (int i=1;i<=m;i++) c[i]+=c[i-1]; for (int i=n;i;i--) sa[c[x[i]]--]=i; for (int k=1;k<=n;k<<=1) { memset(c,0,sizeof c);int cnt=0; for (int i=n-k+1;i<=n;i++) y[++cnt]=i; for (int i=1;i<=n;i++) if (sa[i]>k) y[++cnt]=sa[i]-k; for (int i=1;i<=n;i++) c[x[i]]++; for (int i=1;i<=m;i++) c[i]+=c[i-1]; for (int i=n;i;i--) sa[c[x[y[i]]]--]=y[i],y[i]=0; swap(x,y);cnt=0; x[sa[1]]=++cnt; 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])?cnt:++cnt; m=cnt; } } int main() { scanf("%s",s+1); n=strlen(s+1);m='z'; SA(); for (int i=1;i<=n;i++) printf("%d ",sa[i]); }