[模板] 字尾陣列
阿新 • • 發佈:2018-12-22
概述
字尾陣列(Suffix Array), 是一種將字串所有後綴排序的一種演算法。
通過排序後的字尾,我們可以得到字串的許多性質,如重複出現的字串等。
演算法
常見的字尾陣列演算法有:
- 倍增演算法
- 時間複雜度 $ O(n log n)
- 常數較小
- 程式碼較短
- DC3演算法
- 時間複雜度 $ O(n)
- 常數較大
- 程式碼較長
- SA-IS演算法
- 時間複雜度 $ O(n)
- 常數較大
- 程式碼很長
窩三個月之前還會,現在就不會了
倍增演算法
放兩個連結:
程式碼
#include<cstdio> #include<iostream> #include<cmath> #include<cstring> #include<algorithm> #include<set> #include<map> using namespace std; #define rep(i,l,r) for(register int i=(l);i<=(r);++i) #define repdo(i,l,r) for(register int i=(l);i>=(r);--i) #define il inline typedef double db; typedef long long ll; //--------------------------------------- const int ssz=1e6+5; char s[ssz]; int n,m,t1[ssz],t2[ssz],sa[ssz],c[ssz],*rank=t1,*tp=t2; void pr(){ rep(i,1,n)printf("%d %d %d\n",sa[i],rank[i],tp[i]); } void rsort(){ rep(i,0,m)c[i]=0; rep(i,1,n)++c[rank[i]]; rep(i,1,m)c[i]+=c[i-1]; repdo(i,n,1)sa[c[rank[tp[i]]]--]=tp[i]; } void suffixsort(){ rep(i,1,n)rank[i]=s[i]-'0'+1,tp[i]=i; rsort(); // pr(); for(int w=1,p=0;p<n;m=p,w<<=1){ p=0; rep(i,1,w)tp[++p]=n-w+i; rep(i,1,n)if(sa[i]>w)tp[++p]=sa[i]-w; rsort(); swap(tp,rank); p=1,rank[sa[1]]=1; rep(i,2,n){ rank[sa[i]]=(tp[sa[i-1]]==tp[sa[i]]&&tp[sa[i-1]+w]==tp[sa[i]+w])?p:++p; } // pr(); } } void init(){ m=75; suffixsort(); } int main(){ ios::sync_with_stdio(0),cin.tie(0); cin>>(s+1); n=strlen(s+1); init(); rep(i,1,n)cout<<sa[i]<<' '; cout<<'\n'; return 0; }