sa[i] 表示排名第i的是前缀str(sa[i]), rank[i]表示前缀str(i)的排名。
void build_sa(int m) { int *x = t, *y = t2; for(int i = 0; i < m; i ++) c[i] = 0; for(int i = 0; i < n; i ++) c[x[i]=s[i]] ++; for(int i = 1; i < m; i ++) c[i] += c[i-1]; for(int i = n-1; i >= 0; i --) sa[--c[x[i]]] = i; for(int k = 1; k <= n; k <<= 1) { int p = 0; for(int i = n-k; i < n; i ++) y[p++] = i; for(int i = 0; i < n; i ++) if(sa[i] >= k) y[p++] = sa[i] - k; for(int i = 0; i < m; i ++) c[i] = 0; for(int i = 0; i < n; i ++) c[x[y[i]]]++; for(int i = 1; i < m; i ++) c[i] += c[i-1]; for(int i = n-1; i >= 0; i --) sa[--c[x[y[i]]]] = y[i]; swap(x,y); p = 1; x[sa[0]] = 0; for(int i = 1; i < n; i ++) x[sa[i]] = y[sa[i-1]] == y[sa[i]] && y[sa[i-1]+k] == y[sa[i]+k]?p-1:p++; if(p >= n)break; m = p; } }
#define maxn 1000001 int wa[maxn],wb[maxn],wv[maxn],ws[maxn]; 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 ++) ws[i] = 0; for(i = 0; i < n; i ++) ws[x[i] = r[i]]++; for(i = 1; i < m; i ++) ws[i] += ws[i-1]; for(i = n-1; i >= 0; i --) sa[--ws[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 ++) ws[i] = 0; for(i = 0; i < n; i ++) ws[wv[i]]++; for(i = 1; i < m; i ++) ws[i] += ws[i-1]; for(i = n-1; i >= 0; i --) sa[--ws[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++; } return; } 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++); return; } int RMQ[maxn]; int mm[maxn]; int best[20][maxn]; void initRMQ(int n) { int i, j, a, b; for(mm[0] = -1, i = 1; i <= n; i ++) mm[i] = ((i&(i-1))==0)?mm[i-1]+1:mm[i-1]; for(i = 1; i <= n; i ++) best[0][i] = i; for(i = 1; i <= mm[n]; i++) for(j = 1; j <= n+1-(1<<i);j++) { a = best[i-1][j]; b = best[i-1][j+(1<<(i-1))]; if(RMQ[a] < RMQ[b]) best[i][j] = a; else best[i][j] = b; } return; } int askRMQ(int a,int b) { int t; t = mm[b-a+1]; b -= (1<<t)-1; a = best[t][a]; b = best[t][b]; return RMQ[a] < RMQ[b]?a:b; } int lcp(int a,int b) { int t; a = rank[a]; b = rank[b]; if(a>b) {t=a;a=b;b=t;} return(height[askRMQ(a+1,b)]); }