Question: obtain the number of public substrings whose length is not less than k
Continue with the questions on the paper.
Calculate the longest common prefix length between A suffix and B. If the length of L is greater than k, add the L-k + 1 Group.
Concatenate two strings and separate them with a non-existent character. (This is a magic Practice)
Then grouped by the height array, the height of a group is greater than or equal to k, that is, the longest public prefix of any two suffixes is at least k.
Scan it again. When A suffix of B is encountered, it calculates the number of all the satisfied groups based on the previous suffix. However, this method is n ^ 2.
We can find that the longest common prefix of the two suffixes is the minimum value of the height value of this section.
It can be maintained through a monotonous stack. If the elements to be imported into the stack are smaller than the elements at the bottom of the stack, it means that the suffix B added later and the longest public prefix at the bottom of the stack are smaller than or equal to the value of the inbound stack. In this way, the height value in the monotonous stack is absolutely increasing, and gradually merged, and the average spread can reach the complexity of o (n.
Scan twice.
[Cpp]
# Include <iostream>
# Include <cstdio>
# Include <cstring>
# Include <algorithm>
# Include <cmath>
# Define N 100005
# Define LL long
# Define maxn200005
Using namespace std;
// Obtain the suffix Array Using the multiplication algorithm.
Int wa [maxn], wb [maxn], wv [maxn], Ws [maxn];
Int cmp (int * r, int a, int B, int l)
{Return r [a] = r [B] & r [a + l] = r [B + l];}
Void da (const char * r, int * sa, int n, int m ){
Int I, j, p, * x = wa, * y = wb, * t;
For (I = 0; I <m; I ++) Ws [I] = 0;
For (I = 0; I <n; I ++) Ws [x [I] = r [I] ++;
For (I = 1; I <m; I ++) Ws [I] + = Ws [I-1];
For (I = n-1; I> = 0; I --) sa [-- Ws [x [I] = I;
For (j = 1, p = 1; p <n; j * = 2, m = p ){
For (p = 0, 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 <n; I ++) wv [I] = x [y [I];
For (I = 0; I <m; I ++) Ws [I] = 0;
For (I = 0; I <n; I ++) Ws [wv [I] ++;
For (I = 1; I <m; I ++) Ws [I] + = Ws [I-1];
For (I = n-1; I> = 0; I --) sa [-- Ws [wv [I] = y [I];
For (t = x, x = y, y = t, p = 1, x [sa [0] = 0, I = 1; I <n; I ++)
X [sa [I] = cmp (y, sa [I-1], sa [I], j )? P-1: p ++;
}
Return;
}
Int sa [maxn], Rank [maxn], height [maxn];
// Calculate the height Array
Void calheight (const char * r, int * sa, int n ){
Int I, j, k = 0;
For (I = 1; I <= n; I ++) Rank [sa [I] = I;
For (I = 0; I <n; height [Rank [I ++] = k)
For (k? K --: 0, j = sa [Rank [I]-1]; r [I + k] = r [j + k]; k ++ );
Return;
}
Char str [maxn], ch [maxn];
Int k;
Int s [maxn] [2];
LL tot, top;
Int main (){
While (scanf ("% d", & k )! = EOF & k ){
Int l1, l2;
Scanf ("% s", str, ch );
L1 = strlen (str); l2 = strlen (ch );
Str [l1] = '@';
For (int I = l1 + 1; I <= l1 + l2; I ++)
Str [I] = ch [i-l1-1];
Int n = l1 + l2 + 1;
Str [n] = '\ 0 ';
Da (str, sa, n + 1,130 );
Calheight (str, sa, n );
Tot = top = 0;
LL sum = 0;
For (int I = 1; I <= n; I ++ ){
If (height [I] <k) top = tot = 0;
Else {
Int cnt = 0;
If (sa [I-1] <l1) cnt ++, tot + = height [I]-k + 1;
While (top> 0 & height [I] <= s [top-1] [0]) {
Top --;
Tot-= s [top] [1] * (s [top] [0]-height [I]);
Cnt + = s [top] [1];
}
S [top] [0] = height [I]; s [top ++] [1] = cnt;
If (sa [I]> l1) sum + = tot;
}
}
Tot = top = 0;
For (int I = 1; I <= n; I ++ ){
If (height [I] <k) top = tot = 0;
Else {
Int cnt = 0;
If (sa [I-1]> l1) cnt ++, tot + = height [I]-k + 1;
While (top> 0 & height [I] <= s [top-1] [0]) {
Top --;
Tot-= s [top] [1] * (s [top] [0]-height [I]);
Cnt + = s [top] [1];
}
S [top] [0] = height [I]; s [top ++] [1] = cnt;
If (sa [I] <l1) sum + = tot;
}
}
Printf ("% I64d \ n", sum );
}
Return 0;
}
# Include <iostream>
# Include <cstdio>
# Include <cstring>
# Include <algorithm>
# Include <cmath>
# Define N 100005
# Define LL long
# Define maxn200005
Using namespace std;
// Obtain the suffix Array Using the multiplication algorithm.
Int wa [maxn], wb [maxn], wv [maxn], Ws [maxn];
Int cmp (int * r, int a, int B, int l)
{Return r [a] = r [B] & r [a + l] = r [B + l];}
Void da (const char * r, int * sa, int n, int m ){
Int I, j, p, * x = wa, * y = wb, * t;
For (I = 0; I <m; I ++) Ws [I] = 0;
For (I = 0; I <n; I ++) Ws [x [I] = r [I] ++;
For (I = 1; I <m; I ++) Ws [I] + = Ws [I-1];
For (I = n-1; I> = 0; I --) sa [-- Ws [x [I] = I;
For (j = 1, p = 1; p <n; j * = 2, m = p ){
For (p = 0, 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 <n; I ++) wv [I] = x [y [I];
For (I = 0; I <m; I ++) Ws [I] = 0;
For (I = 0; I <n; I ++) Ws [wv [I] ++;
For (I = 1; I <m; I ++) Ws [I] + = Ws [I-1];
For (I = n-1; I> = 0; I --) sa [-- Ws [wv [I] = y [I];
For (t = x, x = y, y = t, p = 1, x [sa [0] = 0, I = 1; I <n; I ++)
X [sa [I] = cmp (y, sa [I-1], sa [I], j )? P-1: p ++;
}
Return;
}
Int sa [maxn], Rank [maxn], height [maxn];
// Calculate the height Array
Void calheight (const char * r, int * sa, int n ){
Int I, j, k = 0;
For (I = 1; I <= n; I ++) Rank [sa [I] = I;
For (I = 0; I <n; height [Rank [I ++] = k)
For (k? K --: 0, j = sa [Rank [I]-1]; r [I + k] = r [j + k]; k ++ );
Return;
}
Char str [maxn], ch [maxn];
Int k;
Int s [maxn] [2];
LL tot, top;
Int main (){
While (scanf ("% d", & k )! = EOF & k ){
Int l1, l2;
Scanf ("% s", str, ch );
L1 = strlen (str); l2 = strlen (ch );
Str [l1] = '@';
For (int I = l1 + 1; I <= l1 + l2; I ++)
Str [I] = ch [i-l1-1];
Int n = l1 + l2 + 1;
Str [n] = '\ 0 ';
Da (str, sa, n + 1,130 );
Calheight (str, sa, n );
Tot = top = 0;
LL sum = 0;
For (int I = 1; I <= n; I ++ ){
If (height [I] <k) top = tot = 0;
Else {
Int cnt = 0;
If (sa [I-1] <l1) cnt ++, tot + = height [I]-k + 1;
While (top> 0 & height [I] <= s [top-1] [0]) {
Top --;
Tot-= s [top] [1] * (s [top] [0]-height [I]);
Cnt + = s [top] [1];
}
S [top] [0] = height [I]; s [top ++] [1] = cnt;
If (sa [I]> l1) sum + = tot;
}
}
Tot = top = 0;
For (int I = 1; I <= n; I ++ ){
If (height [I] <k) top = tot = 0;
Else {
Int cnt = 0;
If (sa [I-1]> l1) cnt ++, tot + = height [I]-k + 1;
While (top> 0 & height [I] <= s [top-1] [0]) {
Top --;
Tot-= s [top] [1] * (s [top] [0]-height [I]);
Cnt + = s [top] [1];
}
S [top] [0] = height [I]; s [top ++] [1] = cnt;
If (sa [I] <l1) sum + = tot;
}
}
Printf ("% I64d \ n", sum );
}
Return 0;
}