Hdu4416 Good Article Good sentence (suffix array)
Question: How many consecutive substrings are not in string B in string. The length of a is 10 ^ 5, and the total length of B cannot exceed 10 ^ 5.
Solution: suffix array question; suffix array can easily calculate the number of seed strings in a string. Concatenate a and B sets, calculate the number of different substrings at a time, and then subtract the number of substrings that B connects to each other. To remove a substring containing a link character, scan the substring to enumerate the last occurrence of the connector.
Code:
/*************************************** * *************** @ Author: xiefubao *************************************** * ***************/# pragma comment (linker, "/STACK: 102400000,102400000") # include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
# Include
// Freopen ("in.txt", "r", stdin); using namespace std; # define eps 1e-8 # define zero (_) (abs (_) <= eps) const double pi = acos (-1.0); typedef long LL; const ll inf = 0x3FFFFFFF; const int MAX = 300010; int n, num [MAX]; char s [MAX]; int sa [MAX], rank [MAX], height [MAX]; // sa [I] indicates the position of the suffix of the ranking I, height [I] indicates the longest common prefix of SA [I] and SA [I-1] int wa [MAX], wb [MAX], wv [MAX], wd [MAX]; /** suffix array * Multiplication Algorithm O (n * logn) * The length of the array to be sorted is n, which is placed between 0 and ~ In n-1, add a 0 * da (str, n + 1, sa, rank, height,) at the end; // note that it is n + 1; * For example: * n = 8; * num [] = {1, 1, 2, 1, 1, 1, 1, 2, $}; note that the last digit of num is 0, other values greater than 0 * rank [] = {4, 6, 8, 1, 2, 3, 5, 7, 0}; rank [0 ~ N-1] is a valid value. rank [n] Must be 0. The value * sa [] = {8, 3, 4, 5, 0, 6, 1, 7, 2} is invalid }; sa [1 ~ N] is a valid value, sa [0] Must be n is an invalid value * height [] = {0, 0, 3, 2, 3, 1, 2, 0, 1 }; height [2 ~ N] is the valid value **/int t1 [MAX], t2 [MAX], c [MAX]; // obtain the intermediate variable required by the SA array, no value assignment is required. // the string to be sorted is placed in the s array, from s [0] To s [n-1]. The length is n and the maximum value is less than m, // All s [I] Except s [n-1] are greater than 0, r [n-1] = 0 // After the function ends, the result is placed in the sa array bool cmp (int * r, int a, int B, int l) {return r [a] = r [B] & r [a + l] = r [B + l];} void da (int str [], int n, int m) {n ++; int I, j, p, * x = t1, * y = t2; // first round of base sorting, if the maximum value of s is large, you can change it to Quick Sort for (I = 0; I <m; I ++) c [I] = 0; 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; for (j = 1; j <= n; j <= 1) {p = 0; // sort the second keyword for (I = n-j; I <n; I ++) y [p ++] = I using the sa array directly; // The minimum for (I = 0; I <n; I ++) if (sa [I]> = j) y [p ++] = sa [I]-j; // in this way, array y stores the result sorted by the second keyword. // The first keyword is sorted by the base number. 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 = n-1; I> = 0; I --) sa [-- c [x [y [I] = y [I]; // calculate the new x array swap (x, y) based on the sa and x arrays; p = 1; x [sa [0] = 0; for (I = 1; I <n; I ++) x [sa [I] = cmp (y, sa [I-1], sa [I], j )? P-1: p ++; if (p> = n) break; m = p; // maximum value of the next base sort} int k = 0; n --; 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 (str [I + k] = str [j + k]) k ++; height [rank [I] = k ;}} void da1 (int * r, int n, int m) // multiplier algorithm 0 (nlgn ). {Int I, j, p, * x = wa, * y = wb, * t; for (I = 0; I <m; I ++) wd [I] = 0; for (I = 0; I <n; I ++) wd [x [I] = r [I] ++; for (I = 1; I <m; I ++) wd [I] + = wd [I-1]; for (I = n-1; I> = 0; I --) sa [-- wd [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 ++) wd [I] = 0; for (I = 0; I <n; I ++) wd [wv [I] ++; for (I = 1; I <m; I ++) wd [I] + = wd [I-1]; for (I = n-1; I> = 0; I --) sa [-- wd [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 ++ ;}}ll get (int * p, int m, int hh) {da (p, m, hh + 2 ); LL ans = 0; for (int I = 2; I <= m; I ++) {ans + = m-sa [I-1]-height [I];} ans + = m-sa [m]; LL last =-1; for (int I = 0; I
= 39) {if (last =-1) last = I; else {ans-= (I-last) * (last + 1); last = I ;}}} if (last! =-1) ans-= (m-last) * (last + 1); return ans;} int main () {int t; cin> t; int kk = 1; while (t --) {scanf ("% d", & n); scanf ("% s", s); int len = strlen (s ); int sum = 0; for (int I = 0; I