POJ 3415 Common Substrings (suffix array + monotonous stack)

Source: Internet
Author: User

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;
}
 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.