char s[N];
int sa[N],rank[N],h[N],n,m,len;
int cnt[N],val[N],stk[N],_val[N],top;
bool issame(int a,int b,int hl)
{
if(val[a]!=val[b])return 0;
if(a+hl>len&&b+hl>len)return 1;
if(a+hl<len&&b+hl<len)return val[a+hl]==val[b+hl];
return 0;
}
void SA(int lim)
{
int i,j,k,hl;
for(i=0;i<lim;i++)cnt[i]=0;
for(i=0;i<len;i++)cnt[val[i]=s[i]-'a']++;
for(i=1;i<lim;i++)cnt[i]+=cnt[i-1];
for(i=len-1;i>=0;i--)sa[--cnt[val[i]]]=i;
for(k=1;;k++)
{
top=0,hl=1<<(k-1);
for(i=0;i<len;i++)if(sa[i]+hl>=len)stk[top++]=sa[i];
for(i=0;i<len;i++)if(sa[i]>=hl)stk[top++]=sa[i]-hl;
for(i=0;i<lim;i++)cnt[i]=0;
for(i=0;i<len;i++)cnt[val[i]]++;
for(i=1;i<lim;i++)cnt[i]+=cnt[i-1];
for(i=len-1;i>=0;i--)sa[--cnt[val[stk[i]]]]=stk[i];
for(lim=i=0;i<len;lim++)
{
for(j=i;j<len-1&&issame(sa[j],sa[j+1],hl);j++);
for(;i<=j;i++)_val[sa[i]]=lim;
}
for(i=0;i<len;i++)val[i]=_val[i];
if(lim==len)break;
}
for(i=0;i<len;i++)rank[sa[i]]=i;
for(i=0;i<len;i++)
{
if(k)k--;
if(!rank[i])continue;
while(s[i+k]==s[sa[rank[i]-1]+k])k++;
h[rank[i]]=k;
}
}
后缀数组模板(基数排序版),带height和rank
最新推荐文章于 2022-05-13 16:36:10 发布