const int maxn = 2e5+10;
char s[maxn];
int y[maxn],x[maxn],c[maxn],sa[maxn],rk[maxn],height[maxn];
void get_SA(int n,int m)//n表示待求串s的长度,下标由1开始,m表示max(s[i])
{
for(int i=1;i<=m;++i) c[i]=0;//桶的初始化
for (int i=1;i<=n;++i) ++c[x[i]=s[i]];
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)
{
int 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],y[i]=0;
swap(x,y);
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 (num==n) break;
m=num;
}
}
void get_height(int n)
{
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]];
}
}
后缀数组(倍增)【模板】
最新推荐文章于 2024-12-29 22:51:15 发布