准备学习后缀数组 先存一个论文里的模板
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> using namespace std; #define F(x) ((x) / 3 + ((x) % 3 == 1 ? 0 : tb)) #define G(x) ((x) < tb ? (x) * 3 + 1 :((x) - tb) * 3 + 2) const int MAXN = 300010; const int MAXM = 100010; char input[MAXM]; int wa[MAXN],wb[MAXN],ws[MAXN],wv[MAXN],wsd[MAXN],r[MAXN],sa[MAXN]; int num[MAXN]; char str[MAXN]; int dp[MAXM][25]; int c0(int *r,int a,int b) { return r[a] == r[b] && r[a + 1] == r[b + 1] && r[a + 2] == r[b + 2]; } int c12(int k,int *r,int a,int b) { if(k == 2) return r[a] < r[b] || r[a] == r[b] && c12(1,r,a + 1,b + 1); else return r[a] < r[b] || r[a] == r[b] && wv[a + 1]< wv[b + 1]; } void mysort(int *r,int *a,int *b,int n,int m) { int i; for(i = 0 ; i < n ; i++) wv[i] = r[a[i]]; for(i = 0 ; i < m ; i++) wsd[i] = 0; for(i = 0 ; i < n ; i++) wsd[wv[i]]++; for(i = 1 ; i < m ; i++) wsd[i] += wsd[i - 1]; for(i = n - 1 ; i >= 0 ; i--) b[--wsd[wv[i]]] = a[i]; } void dc3(int *r,int *sa,int n,int m) { int i,j,*rn = r + n ,*san = sa + n,ta = 0,tb = (n + 1) / 3,tbc = 0,p; r[n] = r[n + 1] = 0; for(i = 0 ; i < n ; i++) if(i % 3 != 0) wa[tbc++] = i; mysort(r + 2,wa,wb,tbc,m); mysort(r + 1,wb,wa,tbc,m); mysort(r,wa,wb,tbc,m); for(p = 1,rn[F(wb[0])] = 0,i = 1 ; i < tbc ; i++) rn[F(wb[i])] = c0(r,wb[i - 1],wb[i])?p - 1 : p++; if(p < tbc) dc3(rn,san,tbc,p); else for(i = 0 ; i < tbc ; i++) san[rn[i]] = i; for(i = 0 ; i < tbc ; i++) if(san[i] < tb) wb[ta++] = san[i] * 3; if(n % 3 == 1) wb[ta++] = n - 1; mysort(r,wb,wa,ta,m); for(i = 0 ; i < tbc ; i++) wv[wb[i] = G(san[i])] = i; for(i = 0,j = 0,p = 0 ; i < ta && j < tbc ; p++) sa[p]=c12(wb[j] % 3,r,wa[i],wb[j]) ? wa[i++] : wb[j++]; for(; i < ta ; p++) sa[p] = wa[i++]; for(; j < tbc ; p++) sa[p] = wb[j++]; } int cmp(int *r,int a,int b,int l) { return r[a ]== r[b] && r[a + l] == r[b + l]; } void da(int *r,int *sa,int n,int m) { int i,j,p,*x = wa,*y = wb,*t; for(i = 0 ; i < m ; i++) wsd[i] = 0; for(i = 0 ; i < n ; i++) wsd[x[i] = r[i]]++; for(i = 1 ; i < m ; i++) wsd[i] += wsd[i - 1]; for(i = n - 1 ; i >= 0 ; i--) sa[--wsd[x[i]]] = i; for(j = 1 , p = 1 ; p < n ; j *= 2,m = p) { for(p = 0 ,i = n - j ; i < n ; i++) y[p++] = i; for(i = 0 ; i < n ; i++) if(sa[i] >= j) y[p++] = sa[i] - j; for(i = 0 ; i < n ; i++) wv[i] = x[y[i]]; for(i = 0 ; i < m ; i++) wsd[i] = 0; for(i = 0 ; i < n ; i++) wsd[wv[i]]++; for(i = 1 ; i < m ; i++) wsd[i] += wsd[i - 1]; for(i = n - 1 ; i >= 0 ; i--) sa[--wsd[wv[i]]] = y[i]; for(t = x,x = y,y = t,p = 1,x[sa[0]] = 0,i = 1; i < n ; i++) x[sa[i]] = cmp(y,sa[i - 1],sa[i],j) ? p - 1 : p++; } } int Rank[MAXN],height[MAXN]; void calheight(int *r,int *sa,int n) { int i,j,k = 0; for(i = 1 ; i <= n ; i++) Rank[sa[i]] = i; for(i = 0 ; i < n ; height[Rank[i++]] = k) for(k ? k--:0,j = sa[Rank[i] - 1] ; r[i + k]==r[j + k]; k++); } void RMQ_init(int n,int b[]) { int i,j; for(i = 1 ; i <= n ; i++) dp[i][0] = b[i]; for(j = 1 ; (1 << j) <= n ; j++) for(i = 1 ; i + (1 << j) - 1 <= n ; i++) dp[i][j] = min(dp[i][j - 1],dp[i + (1<<(j - 1))][j - 1]); } int rmq(int s,int v) { s = Rank[s],v = Rank[v]; if(s > v)swap(s,v); s++; int k=(int)(log((v - s + 1)*1.0)/log(2.0)); return min(dp[s][k],dp[v - (1 << k) + 1][k]); } int main() { while (scanf ("%s",input)!=EOF) { int len=strlen(input); for (int i=0;i<len;i++) { num[i]=input[i]-'0'+1; } num[len]=0; dc3(num,sa,len + 1,11);//带上自定义最小的那个的种类数 calheight(num,sa,len+1); for (int i=0;i<len;i++) printf ("%d ",Rank[i]);printf ("\n"); } return 0; }