Transferred from: http://blog.csdn.net/aozil_yang/article/details/77929216

Test instructions

Tells you a string and a K, to find out how many different substrings in this string happen to be k times.

Ideas:

An array of suffixes.

We first consider the substring that appears at least k times, so we enumerate the ordered suffix I (sa[i]).

Enumeration of K-segment K-segments.

Assuming that the current enumeration is Sa[i]~sa[i + k-1]

So let's say that the longest common prefix in this section is L.

Then there is a different substring of l at least k times.

We're going to subtract at least K + 1, but it has to do with the K-segment LCP, so it's definitely this paragraph looking up for a suffix or a suffix down.

i.e. Sa[i-1] ~ sa[i + k-1] and Sa[i] ~ sa[i + K] two times LCP minus can be.

But it's going to be much less.

The LCP which is obviously sa[i-1] ~ sa[i + k) is significantly reduced. Plus you can.

Note K =1 in the case of LCP will have a problem, that is, to find a string of the longest public prefix will have problems, a special sentence can be.

Must pay attention to boundary problem boundary problem boundary problem!!!

1#include <cstdio>2#include <cstring>3#include <algorithm>4 using namespaceStd5 6 Const intMAXN = 100000 + 10;7 8 intT1[MAXN], T2[MAXN], C[MAXN];9 Ten BOOLcmpint* R,intAintBintL) { One returnR[a] = = R[b] && r[a+l] = = R[b+l]; A} - - voidDaintStr[],intSa[],intRank[],intLcp[],intNintm) { the++n; - intI, J, p, *x = t1, *y = t2; - for(i = 0; i < m; ++i) c[i] = 0; - //Puts ("HHA"); + for(i = 0; i < n; ++i) c[x[i] = str[i]]++; - for(i = 1; i < m; ++i) c[i] + = c[i-1]; + for(i = n-1; I >= 0; i.) sa[--c[x[i]] = i; A for(j = 1; J <= N; J <<= 1) { atp = 0; - for(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 < m; ++i) c[i] = 0; - for(i = 0; i < n; ++i) c[x[y[i]]]++; - in 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]; to +Swap (x, y); -p = 1; X[sa[0]] = 0; the for(i = 1; i < n; ++i) { *X[sa[i]] = cmp (y, sa[i-1], Sa[i], j)? P-1: p++; $ Panax Notoginseng -} the + if(P >= N) Break; AM= p; the + -} $ $ intk = 0; -n--; - for(i = 0; I <= N; ++i) Rank[sa[i]] = i; the for(i = 0; i < n; ++i) { - if(k)--k;Wuyij = Sa[rank[i]-1]; the while(Str[i+k] = = Str[j+k]) ++k; -Lcp[rank[i]] = k; Wu} -} About $ intLCP[MAXN], A[MAXN], SA[MAXN], RANK[MAXN]; - - CharS[MAXN]; - A intD[MAXN][40]; + intLen the - voidRmq_init (intAintN) { $ for(inti = 0; I < n; ++i) d[i][0] = A[i]; the for(intj = 1; (1<<j) <= N; ++J) the for(inti = 0; i + (1<<j)-1 < N; ++i) theD[i][j] = min (d[i][j-1], D[i + (1<< (j-1))][j-1]); the} - in intASK (intLintR) { the intk = 0; the while((1<< (k+1)) <= r-l + 1) ++k; About returnMin (D[l][k], d[r-(1<<k) + 1][k]); the} the the intAskintLintR) { + if(L = = r)returnLEN-SA[R];// L = = R is a string that returns its own length. - returnASK (l + 1, R);/// otherwise in RMQ query. the}Bayi the // the intMain () { - intT -scanf ("%d", &t); the the while(t--) { the intK thescanf ("%d", &k); -scanf ("%s", s); theLen = strlen (s); the for(inti = 0; i < Len; ++i) { theA[i] = s[i]-' a ' + 1;94} theA[len] = 0; theDa (A, SA, Rank, LCP, Len, 30); theRmq_init (LCP, Len + 1);98 Long LongAns = 0; About for(inti = 1; i + k-1 <= len; ++i) { -Ans + = Ask (I, i + k-1);101 if(i-1 > 0) ans-=-ask (i-1, i + k-1);/// pay attention to boundary problems. 102 if(i + k <= len) ans-=-ask (I, i + K);103 if(i-1 > 0 && i + k <= len) ans + = ask (I-1, i + K);104} theprintf ("%i64d\n", ans);106 107 108}109 return0; the}111

"Go" HDU 6194 string string (2017 Shenyang webcast-suffix array)