Topic Link: Click to open the link
Solution idea: After the hight array is processed with the suffix array, the segment is built and the minimum value of the interval is maintained, so we take its minimum value every time we enumerate an interval of length n, which means that the string length from 1-ans_min is satisfied. So the topic also requires exactly n repetition, then we will take another two times a left boundary plus one interval value, one is the right boundary plus one interval value, take two value of Max so this range should be (left and right boundary +1 Max,ans_min], time complexity should be lenlog (len)
Code:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std;
const int MX = 1E5+10;
Char STR[MX];
int C[MX],WA[MX],WB[MX],SA[MX],HIGHT[MX],RAN[MX];
void Sort_sa (int m,int n) {int *x=wa,*y=wb,p=0;
for (int i=0;i<m;i++) c[i]=0;
for (int i=0;i<n;i++) c[x[i]=str[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;p<n;k<<=1,m=p) {p=0;
for (int i=n-k;i<n;i++) y[p++]=i;//is sorted by digit 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); x[sa[0]] = 0,p = 1;
for (int i=1;i<n;i++) if (y[sa[i]]==y[sa[i-1]]&&y[sa[i]+k]==y[sa[i-1]+k]) x[sa[i]]=p-1;
else x[sa[i]]=p++; }} void Gethight () {int k=0,len=strlen (str);
for (int i=1;i<=len;i++) ran[sa[i]]=i;
for (int i=0;i<len;i++) {if (k) k--;
int j=sa[ran[i]-1];
while (Str[j+k]==str[i+k]) k++;
Hight[ran[i]]=k;
}} int sum[mx<<2];
void build (int l,int R,int RT) {if (l==r) {Sum[rt] = hight[l];
return;
} int mid = (l+r) >>1;
Build (l,mid,rt<<1);
Build (mid+1,r,rt<<1|1);
SUM[RT] = min (sum[rt<<1],sum[rt<<1|1]);
} int query (int l,int r,int l,int r,int RT) {if (l<=l&&r>=r) return SUM[RT];
int mid = (l+r) >>1;
int ans = 1e9;
if (mid>=l) ans = query (l,r,l,mid,rt<<1);
if (mid<r) ans = min (ans,query (l,r,mid+1,r,rt<<1|1));
return ans;
} int main () {int t,n;
scanf ("%d", &t);
while (t--) {scanf ("%d", &n);
scanf ("%s", str);
int Len=strlen (str), ans = 0;
Sort_sa (200,len+1);
Gethight ();
HIGHT[LEN+1] = 1e9; Build (1,len,1);
if (N>len) {puts ("0"); Continue
} if (N==1) {ans + = len-sa[1]-hight[2];
Ans + = Len-sa[len]-Hight[len];
for (int i=2;i<len;i++) ans + = Len-sa[i]-max (hight[i],hight[i+1]);
printf ("%d\n", ans);
Continue
} int R = query (2,n,1,len,1), L = min (r,hight[n+1]);
Ans + = r-l;
for (int i=3;i<=len-n+1;i++) {R = query (i,i+n-2,1,len,1), L = max (min (r,hight[i+n-1]), Min (r,hight[i-1]));
Ans + = r-l;
} R = Query (len-n+2,len,1,len,1), L = min (r,hight[len-n+1]);
Ans + = r-l;
printf ("%d\n", ans);
} return 0;
}