Description
A substring of a string T is defined as:
T (
i,
k) =
TiTi+1 ...
ti+k-1, 1≤
i≤
i+k-1≤|
T|.
Given strings a, B and one integer K, we define S, A set of triples (i< /c13>, J, K):
S = {(
i,
J,
K) |
k≥
k,
A(
i,
k) =
B(
J,
K)}.
You is to give the value of | S| For specific A, B and K.
Input
The input file contains several blocks of data. For each block, the first line contains one integer K, followed by and lines containing strings A D B, respectively. The input file is ended by K=0.
1≤| A|, | B| ≤105
1 ≤ K ≤ min{| A|, | B|}
Characters of A and B is all Latin letters.
Output
For each case, output an integer | S|.
Sample Input
2aababaaabaabaa1xxxx0
Test instructions: The number of common substrings with a length not less than K.
Idea: or the topic on the paper. The basic idea is to calculate the length of the longest common prefix between all suffixes of a and all suffixes of B. Add up all parts of the longest public prefix length not less than K. First, two strings are connected together, separated by a character that has not been seen in the middle. After grouping by height values, the next task is to speed up the sum of the longest common prefixes between the suffixes in each group. Scan again, each encounter a suffix of a B to count with the suffix of the preceding a can produce how many lengths not less than K of the common substring, where a suffix need to use a monotonous stack for efficient maintenance. Then do it again for A.
More difficult to understand is the monotonous stack of this part. or by example, if the current height[] array is ranked in the order of:-------------. If these are all greater than or equal to K values, and sa[0],sa[1],sa[2] are B-strings, when Sa[3] is a string, the longest common prefix for it and sa[2] is 3, So can be included in the first 3 B string, so can all add up, but if it is less than equals, such as 1, then the value of 2 and 3 need to calculate again, because the longest public prefix is 1, we also need a num[] array to record at this time is greater than or equal to the top of the stack of the number of values, Because this is later if there is a smaller time. It is also necessary to reduce these more than equals.
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <cmath>#include <queue>typedef Long Longllusing namespace STD;Const intMAXN =200010;intSA[MAXN];intT1[MAXN], T2[MAXN], C[MAXN];intRANK[MAXN], HEIGHT[MAXN];voidBuild_sa (intS[],intNintm) {intI, J, p, *x = t1, *y = t2; for(i =0; I < m; i++) C[i] =0; for(i =0; I < n; i++) C[x[i] = s[i]]++; for(i =1; I < m; i++) C[i] + = c[i-1]; for(i = n1; I >=0; i--) Sa[--c[x[i]] = i; for(j =1; J <= N; J <<=1) {p =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]]]++; for(i =1; I < m; i++) C[i] + = c[i-1]; for(i = n1; 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] = y[sa[i-1] [= Y[sa[i]] && y[sa[i-1]+J] = = Y[sa[i]+j]?
P1: p++;if(P >= N) Break; m = p; }}voidGetHeight (intS[],intN) {intI, j, k =0; for(i =0; I <= N; i++) Rank[sa[i]] = i; for(i =0; I < n; i++) {if(k) k--; j = sa[rank[i]-1]; while(S[i+k] = = S[j+k]) k++; Height[rank[i]] = k; }}intR[MAXN];intST[MAXN], NUM[MAXN];CharSTR1[MAXN], STR2[MAXN];intK, len1, Len2;ll solve (intNintK) {ll I, J, tp, ans =0; ll tot, top; for(i =1; I <= N; i++) {if(Height[i] < k) tot = top =0;Else{TP =0;if(sa[i-1] > len1) {tp =1; Tot + = Height[i]-K +1; } while(Top >0&& St[top] >= height[i]) {tot-= num[top] * (St[top]-height[i]); TP + = Num[top]; top--; } St[++top] = Height[i]; Num[top] = TP;if(Sa[i] < len1) ans + = tot; } } for(i =1; I <= N; i++) {if(Height[i] < k) tot = top =0;Else{TP =0;if(sa[i-1] < LEN1) {TP =1; Tot + = Height[i]-K +1; } while(Top >0&& St[top] >= height[i]) {tot-= num[top] * (St[top]-height[i]); TP + = Num[top]; top--; } St[++top] = Height[i]; Num[top] = TP;if(Sa[i] > len1) ans + = tot; } }returnAns;}intMain () {intI, J; while(scanf("%d", &k)! = EOF && k) {scanf("%s%s", STR1,STR2); for(i =0; Str1[i]; ++i) R[i] = Str1[i]; R[i] =' $ ', len1 = i,i++; for(j =0; str2[j];j++) R[i+j] = Str2[j]; R[I+J] =0;intLen = i + j; Build_sa (R, len+1, -); GetHeight (R, Len);printf("%lld\n", Solve (len, k)); }return 0;}
POJ-3415 Common substrings (suffix array to find the number of common substrings with a length not less than k + monotonic stack optimization)