POJ-3415 Common substrings (suffix array to find the number of common substrings with a length not less than k + monotonic stack optimization)

Source: Internet
Author: User

Description

A substring of a string T is defined as:

T  ( i, k) = TiTi+1 ...  ti+k-1, 1≤ ii+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) | kk, 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 ≤ Kmin{| 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)

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.