后缀数组模板 发表于 2018-01-22 | 分类于 模板 | 12345678910111213141516171819202122232425262728293031323334353637383940414243444546void get_sa(int n){ int m=127; for(int i=1;i<=n;i++) Rank[i]=str[i],tp[i]=i; for(int i=0;i<=m;i++) sum[i]=0; for(int i=1;i<=n;i++) sum[Rank[tp[i]]]++; for(int i=1;i<=m;i++) sum[i]+=sum[i-1]; for(int i=n;i>=1;i--) sa[sum[Rank[tp[i]]]--]=tp[i]; int p=1; for(int len=1;p<n;m=p,len<<=1) { p=0; for(int i=n-len+1;i<=n;i++) tp[++p]=i; for(int i=1;i<=n;i++) if(sa[i]>len) tp[++p]=sa[i]-len; for(int i=0;i<=m;i++) sum[i]=0; for(int i=1;i<=n;i++) sum[Rank[tp[i]]]++; for(int i=1;i<=m;i++) sum[i]+=sum[i-1]; for(int i=n;i>=1;i--) sa[sum[Rank[tp[i]]]--]=tp[i]; swap(Rank,tp); Rank[sa[1]]=1; p=1; for(int i=2;i<=n;i++) Rank[sa[i]]=(tp[sa[i]]==tp[sa[i-1]]&&tp[sa[i]+len]==tp[sa[i-1]+len])?p:++p; } int _lst=0,j; for(int i=1;i<=n;height[Rank[i++]]=_lst) // i -> lpos for(_lst=_lst?_lst-1:_lst,j=sa[Rank[i]-1];str[j+_lst]==str[i+_lst];_lst++);}void get_st(int n){ for(int i=2;i<=n;i++) lg2[i]=lg2[i>>1]+1; for(int i=1;i<=n;i++) st[i][0]=height[i]; for(int j=1;j<=lg2[n];j++) for(int i=1;i<=n&&i+(1<<(j-1))<=n;i++) st[i][j]=min(st[i][j-1],st[i+(1<<(j-1))][j-1]);}int query(int l,int r) //l,r => Rank{ if(l>r) swap(l,r); ++l; //notice int len=lg2[r-l+1]; //printf("%d %d %d %d %d\n",l,r,st[l][len],st[r-(1<<len)+1][len],len); return min(st[l][len],st[r-(1<<len)+1][len]);} 本文作者: Zhang_RQ 本文链接: https://zhang-rq.github.io/2018/01/22/后缀数组模板/ 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!