const int maxn = 50010;
int t1[maxn], t2[maxn], c[maxn], sa[maxn], r[maxn], *rank;
void da(int *r, int *sa, int n, int m)
{
int *x=t1, *y=t2, i, k;
for(i=0; i<m; i++) c[i] = 0;
for(i=0; i<n; i++) c[x[i]=r[i]]++;
for(i=1; i<m; i++) c[i]+=c[i-1];
for(i=n-1; i>=0; i--) sa[--c[x[i]]] = i;
for(k=1; k<=n; k<<=1)
{
int p = 0;
for(i=n-k; i<n; i++) y[p++] = i;
for(i=0; i<n; i++) if(sa[i] >= k) y[p++] = sa[i]-k;
for(i=0; i<m; i++) c[i] = 0;
for(i=0; i<n; i++) c[x[i]]++;
for(i=1; i<m; i++) c[i] += c[i-1];
for(i=n-1; i>=0; i--) sa[--c[x[y[i]]]] = y[i];
swap(x, y) ;
x[n-1] = 0;
p = 1;
for(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;
}
rank = x;
}
int height[maxn];
void get_height(int n)
{
int k = 0;
for(int i=0; i<n; i++)
{
if(k) k--;
int j = sa[rank[i]-1];
while(r[i+k] == r[j+k]) k++;
height[rank[i]] = k;
}
}
int mn[maxn][20];
void init_rmq(int n)
{
for(int i=0; i<=n; i++) mn[i][0] = height[i];
for(int k=1; (1<<k)<=n+1; k++)
for(int i=0; i+(1<<k)-1 <= n; i++)
mn[i][k] = min(mn[i][k-1], mn[i+(1<<k-1)][k-1]);
}
int query(int ql, int qr)
{
if(ql > qr) swap(ql, qr);
ql++;
int k = 0;
while(1<<(k+1) <= qr-ql+1) k++;
return min(mn[ql][k], mn[qr-(1<<k)+1][k]);
}
后缀数组模板
最新推荐文章于 2023-12-15 18:40:21 发布