白书SA模板
int rank[200005],tmp[200005];
bool cmp(int i,int j){
int ri,rj;
if(rank[i]!=rank[j])
return rank[i] < rank[j];
ri=i+k<=n?rank[i+k]:-1;
rj=j+k<=n?rank[j+k]:-1;
return ri < rj;
}
void get_suffix(int *s,int *sa){
int i;
// n=s.length();
for(i=0;i<=n;i++){
sa[i]=i;
rank[i]=i < n?s[i]:-1;
}
for(k=1;k<=n;k*=2){
sort(sa,sa+n,cmp);
tmp[sa[0]]=0;
for(i=1;i<=n;i++)
tmp[sa[i]]=tmp[sa[i-1]]+(cmp(sa[i-1],sa[i])?1:0);
for(i=0;i<=n;i++)
rank[i]=tmp[i];
}
}
白书lcp模板// i i+1
void get_lcp(string s, int *sa, int *lcp){
int n = s.length();
for(int i=0; i<=n; i++) rank[sa[i]] = i;
int h = 0;
lcp[0] = 0;
for(int i=0; i<n; i++){
int j = sa[rank[i]-1];
if(h>0) h--;
for(;j+h<n && i+h<n; h++)
if(s[j+h] != s[i+h]) break;
lcp[rank[i]-1] = h;
}
}
蓝书SA模板(m大了以后需要离散)
void build_sa(int n, int m, int *s){
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=0; 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;
}
}
蓝书lcp(应该对)//i i-1
int rank[maxn], lcp[maxn];
void get_lcp(int *s){
int i, j, k = 0;
for(i=0; i<n; i++) rank[sa[i]] = i;
for(i=0; i<n; i++){
if(k) k--;
int j = sa[rank[i]-1];
while(s[i+k] == s[j+k]) k++;
lcp[rank[i]] = k;
}
}