后缀数组
这几天敲了敲后缀数组的模板;
放个模板
1 void build_sa() 2 { 3 for(int i=0;i<n;i++) 4 x[i]=s[i]-'a',m=max(m,x[i]); 5 for(int i=0;i<n;i++) 6 c[x[i]]++; 7 for(int i=1;i<m;i++) 8 c[i]+=c[i-1]; 9 for(int i=n-1;i>=0;i--) 10 sa[--c[x[i]]]=i; 11 for(int k=1;k<=n;k<<=1) 12 { 13 int p=0; 14 for(int i=n-k;i<n;i++)y[p++]=i; 15 for(int i=0;i<n;i++)if(sa[i]>=k)y[p++]=sa[i]-k; 16 17 for(int i=0;i<m;i++)c[i]=0; 18 for(int i=0;i<n;i++)c[x[y[i]]]++; 19 for(int i=1;i<m;i++)c[i]+=c[i-1]; 20 for(int i=0;i<n;i++)sa[--c[x[y[i]]]]=i; 21 22 swap(x,y); 23 p=1;x[sa[0]]=0; 24 for(int i=1;i<n;i++) 25 x[sa[i]]=y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]?p-1:p++; 26 27 if(p>=n)break; 28 m=p; 29 } 30 for(int i=0;i<n;i++)rank[sa[i]]=i; 31 int k=0; 32 for(int i=0;i<n;i++) 33 { 34 if(k)k--; 35 int j=sa[rank[i]-1]; 36 while(s[i+k]==s[j+k])k++; 37 height[rank[i]]=k; 38 } 39 }
本质就是不断的基数排序-更新-基数排序;
复杂度n*logn;
//////////////////////////////////////////////////下面会放题/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
【NOI】品酒大会
(晚上补;