Analysis:
The height array is calculated and the interval minimum value is maintained by monotone queue. The value of the interval minimum of a height array is the longest common prefix for the suffix adjacent to the rank. is actually dividing all the strings into suffixes. Here is an overlapping substring.
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace
Std #define PR (x) cout << #x << ": << x <<" "#define PL (x) cout << #x <<": "<&L T
x << Endl;
static const int MAXN = INT (2e4) + 13;
Suffix array template, time complexity nlogn, space complexity n struct Suffix {int R[MAXN];
The suffix array, the noun array, the height array (representing the longest prefix length of its previous suffix, meaning from 2).
int SA[MAXN],RNK[MAXN],HEIGHT[MAXN];
int t[maxn],t2[maxn],c[maxn],n,m;
Char STR[MAXN];
Converts string to r[i] void init_string (string &s) {n = s.size ();
for (int i=0;i<n;i++) r[i]= (int) s[i];
m = 128;
} void Init_char (char *s) {n = strlen (s);
for (int i=0;i<n;i++) r[i]= (int) s[i];
m = 128;
int cmp (int *r,int a,int b,int l) {return r[a]==r[b]&&r[a+l]==r[b+l];}
Processing gets the suffix array void build () {int i,k,p,*x=t,*y=t2;
r[n++]=0; 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,p=1, k<n; k*=2,m=p) {for (p=0,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[y[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);
P=1;
x[sa[0]]=0;
For (I=1 i<n; i++) x[sa[i]]=cmp (y,sa[i-1],sa[i],k)? p-1:p++;
} n--;
}//Processing get height array and rank array void LCP () {int I, j, k = 0;
For (I=1 i <= n; i++) rnk[sa[i]]=i;
for (i=0 i < n; i++) {if (k) k--;
j = Sa[rnk[i]-1];
while (R[i + K]==r[j + K]) k++;
Height[rnk[i]] = k;
}
}
};
struct Jibancanyang { int QUE[MAXN];
void Fun () {int n, K;
scanf ("%d%d", &n, &k);
String str;
for (int i = 0; i < n; ++i) {int x;
scanf ("%d", &x);
STR + + char (x + ' 0 ');
} if (k = = 1) {printf ("%d\n", N);
Return
} Suffix now;
Now.init_string (str);
Now.build ();
NOW.LCP ();
int head = 0, tail = 0;
int L = 2, R = 2, ans = 0;
while (r <= N) {while (R-l < k-1) {if (R > N) break;
int x = now.height[r++];
while (tail!= head && x < que[tail-1])--tail;
que[tail++] = x;
} if (r > N) break;
ans = max (ans, que[head]);
if (que[head] = = now.height[l++]) head++;
printf ("%d\n", ans);
}}ac;
int main () {#ifdef local freopen ("In.txt", "R", stdin);Freopen ("OUT.txt", "w", stdout);
#endif Ac.fun ();
return 0;
}