During the competition, I used an array with a suffix, but T.
After the game, I read the question report and said that the suffix array seems to be the time of your constant. I have calculated the complexity O (T * Q * n ). This is 10 ^ 8, but considering that the character needs to be re-constructed every time you ask, the n may be (3-4) * n, and the card may be this constant. And then it cannot be.
I first caught the code of my suffix array, and T was so bad.
Because at that time, there was no Suffix of automatic machines.
# Include <iostream> # include <string> # include <cstring> # include <algorithm> # include <cstdio> using namespace std; const int N = 2005; /***** suffix array template *****/# define F (x)/3 + (x) % 3 = 1? 0: tb) // F (x) To find the starting position of suffix (x) of the original string in the new string # define G (x) <tb? (X) * 3 + 1 :( (x)-tb) * 3 + 2) // G (x) is the position of the new string suffix (x) in the original string, and F (x) are reciprocal operations int wa [N], wb [N], wv [N], WS [N]; int sa [N * 3]; int rank1 [N], height [N]; int r [N * 3]; int c0 (int * r, int a, int B) {return r [a] = r [B] & r [a + 1] = r [B + 1] & r [a + 2] = r [B + 2];} int c12 (int k, int * r, int a, int B) {if (k = 2) return r [a] <r [B] | (r [a] = r [B] & c12 (1, r, a + 1, B + 1 )); else return r [a] <r [B] | (r [a] = r [B] & wv [a + 1] <wv [B + 1]) ;} void so Rt (int * r, int * a, int * B, int n, int m) {int I; for (I = 0; I <n; I ++) wv [I] = r [a [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 --) B [-- WS [wv [I] = a [I]; return;} // Note: To facilitate recursive processing, the size of the r array and sa array is 3 * n void dc3 (int * r, int * sa, int n, int m) {// The rn array stores the new recursive string. The san array is the sa int I, j, * rn = r + n, * san = sa + n, ta = 0, tb = (n + 1)/3, tb C = 0, p; r [n] = r [n + 1] = 0; for (I = 0; I <n; I ++) {if (I % 3! = 0) wa [tbc ++] = I; // tbc indicates the number of suffixes where the modulo 3 is 1 or 2 at the starting position} sort (r + 2, wa, wb, tbc, m); sort (r + 1, wb, wa, tbc, m); sort (r, wa, wb, tbc, m); for (p = 1, rn [F (wb [0])] = 0, I = 1; I <tbc; I ++) rn [F (wb [I])] = c0 (r, wb [I-1], wb [I])? P-1: p ++; if (p <tbc) dc3 (rn, san, tbc, p); else {for (I = 0; I <tbc; I ++) san [rn [I] = I ;}// sorts all suffixes where the starting position modulo 3 is equal to 0 for (I = 0; I <tbc; I ++) {if (san [I] <tb) wb [ta ++] = san [I] * 3;} if (n % 3 = 1) // n % 3 = 1, special processing of suffix (n-1) wb [ta ++] = n-1; sort (r, wb, wa, ta, m ); for (I = 0; I <tbc; I ++) wv [wb [I] = G (san [I])] = I; // merge the sorting results of all suffixes and save them in the sa array for (I = 0, j = 0, p = 0; I <ta & j <tbc; p ++) sa [p] = c12 (wb [j] % 3, r, wa [I], wb [j])? Wa [I ++]: wb [j ++]; for (; I <ta; p ++) sa [p] = wa [I ++]; (; j <tbc; p ++) sa [p] = wb [j ++]; return ;}// height [I] = suffix (sa [I-1]) the longest public prefix of suffix (sa [I]), that is, the longest public prefix of the two adjacent suffixes void calheight (int * r, int * sa, int n) {int I, j, k = 0; for (I = 1; I <= n; I ++) rank1 [sa [I] = I; for (I = 0; I <n; height [rank1 [I ++] = k) for (k? K --: 0, j = sa [rank1 [I]-1]; r [I + k] = r [j + k]; k ++ );} int solve (int n) {int I, sum = 0; for (I = 1; I <= n; I ++) {sum + = n-sa [I]-height [I];} return sum;}/***** template ***/char now [2005]; char str [N]; inline void RD (int & ret) {char c; do {c = getchar ();} while (c <'0' | c> '9'); ret = c-'0'; while (c = getchar ()> = '0' & c <= '9') ret = ret * 10 + (c-'0');} inline void OT (int) {if (a> = 10) OT (a/10); putchar (a % 10 + '0');} struct QU {int s, e, id;} QQ [10005]; bool cmp (QU a, QU B) {if (. s = B. s) return. e <B. e; return. s <B. s;} int ans [11111]; int main () {int I, n, t; scanf ("% d", & t); while (t --) {scanf ("% s", str); memset (ans, 0, sizeof (ans); int xd; cin> xd; for (int I = 0; I <xd; I ++) {RD (QQ [I]. s); RD (QQ [I]. e); QQ [I]. s --; QQ [I]. e --; QQ [I]. id = I;} Sort (QQ, QQ + xd, cmp); int st = QQ [0]. s; int ed = QQ [0]. e; int num = 0; for (int I = st; I <= ed; I ++) r [num ++] = (int) str [I]; r [num] = 0; dc3 (r, sa, num + 1,200); calheight (r, sa, num); ans [QQ [0]. id] = solve (num); for (int I = 1; I <xd; I ++) {if (QQ [I]. s! = QQ [I-1]. s) {num = 0; for (int j = QQ [I]. s; j <= QQ [I]. e; j ++) r [num ++] = (int) str [j]; r [num] = 0; dc3 (r, sa, num + 1,200 ); calheight (r, sa, num); ans [QQ [I]. id] = solve (num); ed = QQ [I]. e;} else {if (QQ [I]. e = QQ [I-1]. e) {ans [QQ [I]. id] = ans [QQ [I-1]. id];} else {for (int j = ed + 1; j <= QQ [I]. e; j ++) r [num ++] = (int) str [j]; r [num] = 0; dc3 (r, sa, num + 1,200); c Alheight (r, sa, num); ans [QQ [I]. id] = solve (num); ed = QQ [I]. e ;}}for (int I = 0; I <xd; I ++) {OT (ans [I]); puts ("");}} return 0 ;}# include <iostream >#include <string >#include <cstring >#include <algorithm> # include <cstdio> using namespace std; const int N = 2005; /***** suffix array template *****/# define F (x)/3 + (x) % 3 = 1? 0: tb) // F (x) To find the starting position of suffix (x) of the original string in the new string # define G (x) <tb? (X) * 3 + 1 :( (x)-tb) * 3 + 2) // G (x) is the position of the new string suffix (x) in the original string, and F (x) are reciprocal operations int wa [N], wb [N], wv [N], WS [N]; int sa [N * 3]; int rank1 [N], height [N]; int r [N * 3]; int c0 (int * r, int a, int B) {return r [a] = r [B] & r [a + 1] = r [B + 1] & r [a + 2] = r [B + 2];} int c12 (int k, int * r, int a, int B) {if (k = 2) return r [a] <r [B] | (r [a] = r [B] & c12 (1, r, a + 1, B + 1 )); else return r [a] <r [B] | (r [a] = r [B] & wv [a + 1] <wv [B + 1]) ;} void sort (int * r, Int * a, int * B, int n, int m) {int I; for (I = 0; I <n; I ++) wv [I] = r [a [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 --) B [-- WS [wv [I] = a [I]; return;} // Note: To facilitate recursive processing, the size of the r array and sa array is 3 * nvoid dc3 (int * r, int * sa, int n, int m) {// The rn array stores the new recursive string. The san array is the sa int I, j, * rn = r + n, * san = sa + n, ta = 0, tb = (n + 1)/3, tbc = 0, p; r [N] = r [n + 1] = 0; for (I = 0; I <n; I ++) {if (I % 3! = 0) wa [tbc ++] = I; // tbc indicates the number of suffixes where the modulo 3 is 1 or 2 at the starting position} sort (r + 2, wa, wb, tbc, m); sort (r + 1, wb, wa, tbc, m); sort (r, wa, wb, tbc, m); for (p = 1, rn [F (wb [0])] = 0, I = 1; I <tbc; I ++) rn [F (wb [I])] = c0 (r, wb [I-1], wb [I])? P-1: p ++; if (p <tbc) dc3 (rn, san, tbc, p); else {for (I = 0; I <tbc; I ++) san [rn [I] = I ;}// sorts all suffixes where the starting position modulo 3 is equal to 0 for (I = 0; I <tbc; I ++) {if (san [I] <tb) wb [ta ++] = san [I] * 3;} if (n % 3 = 1) // n % 3 = 1, special processing of suffix (n-1) wb [ta ++] = n-1; sort (r, wb, wa, ta, m ); for (I = 0; I <tbc; I ++) wv [wb [I] = G (san [I])] = I; // merge the sorting results of all suffixes and save them in the sa array for (I = 0, j = 0, p = 0; I <ta & j <tbc; p ++) sa [p] = c12 (wb [j] % 3, r, wa [I], wb [j])? Wa [I ++]: wb [j ++]; for (; I <ta; p ++) sa [p] = wa [I ++]; (; j <tbc; p ++) sa [p] = wb [j ++]; return ;}// height [I] = suffix (sa [I-1]) the longest public prefix of suffix (sa [I]), that is, the longest public prefix of the two adjacent suffixes void calheight (int * r, int * sa, int n) {int I, j, k = 0; for (I = 1; I <= n; I ++) rank1 [sa [I] = I; for (I = 0; I <n; height [rank1 [I ++] = k) for (k? K --: 0, j = sa [rank1 [I]-1]; r [I + k] = r [j + k]; k ++ );} int solve (int n) {int I, sum = 0; for (I = 1; I <= n; I ++) {sum + = n-sa [I]-height [I];} return sum;}/***** template ***/char now [2005]; char str [N]; inline void RD (int & ret) {char c; do {c = getchar ();} while (c <'0' | c> '9'); ret = c-'0'; while (c = getchar ()> = '0' & c <= '9') ret = ret * 10 + (c-'0');} inline void OT (int) {if (a> = 10) OT (a/10 ); Putchar (a % 10 + '0');} struct QU {int s, e, id;} QQ [10005]; bool cmp (QU a, QU B) {if (. s = B. s) return. e <B. e; return. s <B. s;} int ans [11111]; int main () {int I, n, t; scanf ("% d", & t); while (t --) {scanf ("% s", str); memset (ans, 0, sizeof (ans); int xd; cin> xd; for (int I = 0; I <xd; I ++) {RD (QQ [I]. s); RD (QQ [I]. e); QQ [I]. s --; QQ [I]. e --; QQ [I]. id = I;} sort (QQ, QQ + Xd, cmp); int st = QQ [0]. s; int ed = QQ [0]. e; int num = 0; for (int I = st; I <= ed; I ++) r [num ++] = (int) str [I]; r [num] = 0; dc3 (r, sa, num + 1,200); calheight (r, sa, num); ans [QQ [0]. id] = solve (num); for (int I = 1; I <xd; I ++) {if (QQ [I]. s! = QQ [I-1]. s) {num = 0; for (int j = QQ [I]. s; j <= QQ [I]. e; j ++) r [num ++] = (int) str [j]; r [num] = 0; dc3 (r, sa, num + 1,200 ); calheight (r, sa, num); ans [QQ [I]. id] = solve (num); ed = QQ [I]. e;} else {if (QQ [I]. e = QQ [I-1]. e) {ans [QQ [I]. id] = ans [QQ [I-1]. id];} else {for (int j = ed + 1; j <= QQ [I]. e; j ++) r [num ++] = (int) str [j]; r [num] = 0; dc3 (r, sa, num + 1,200); c Alheight (r, sa, num); ans [QQ [I]. id] = solve (num); ed = QQ [I]. e ;}}for (int I = 0; I <xd; I ++) {OT (ans [I]); puts ("");}} return 0;} last night and today, I have been watching the suffix automatic machine. Here I recommend a blog that I can understand. Http://blog.sina.com.cn/s/blog_70811e1a01014dkz.html is a template. Of course, it is also limited to template questions .. Good water .. Continue learning .. [Cpp] view plaincopyprint? # Include <iostream> # include <cstdio> # include <algorithm> # include <string> # include <cmath> # include <cstring> # include <queue> # include <set> # include <vector> # include <stack> # include <map> # include <iomanip> # define PI acos (-1.0) # define Max 2505 # define inf 1 <28 # define LL (x) (x <1) # define RR (x) (x <1 | 1) # define REP (I, s, t) for (int I = (s); I <= (t); ++ I) # define ll long Long # define mem (a, B) memset (a, B, sizeof (a) # define mp (a, B) make_pair (a, B) # define PII pair <int, int> using namespace std; inline void RD (int & ret) {char c; do {c = getchar ();} while (c <'0' | c> '9'); ret = c-'0'; while (c = getchar ()> = '0' & c <= '9') ret = ret * 10 + (c-'0');} inline void OT (int) {if (a> = 10) OT (a/10); putchar (a % 10 + '0');} struct SAM {SAM * pre, * next [26]; Int val; void clear () {pre = 0; val = 0; mem (next, 0) ;}}; SAM * root, * last, * cur; SAM qe [111111]; int cnt = 0; void init () {cnt = 0; root = last = & qe [cnt ++]; root-> clear ();} struct QU {int s, e, id;} QQ [100005]; void extend (int w) {SAM * p = last; SAM * np = & qe [cnt ++]; np-> clear (); np-> val = p-> val + 1; while (p &&! P-> next [w]) p-> next [w] = np, p = p-> pre; if (! P) {np-> pre = root;} else {SAM * q = p-> next [w]; if (p-> val + 1 = q-> val) {np-> pre = q;} else {SAM * nq = & qe [cnt ++]; nq-> clear (); memcpy (nq-> next, q-> next, sizeof (q-> next); nq-> val = p-> val + 1; nq-> pre = q-> pre; q-> pre = nq; np-> pre = nq; while (p & p-> next [w] = q) {p-> next [w] = nq; p = p-> pre ;}}last = np ;}# define N 100005 # define M 2005 char a [M]; bool cmp (QU a, QU B) {if (. s = B. s) return. e <B. e; return. s <B. s;} int solve () {int sum = 0; for (int I = cnt-1; I> 0; I --) {sum + = qe [I]. val-qe [I]. pre-> val;} return sum;} int ans [N]; int main () {int T; cin> T; while (T --) {cin>; mem (ans, 0); int l = strlen (a); int Q; cin> Q; for (int I = 0; I <Q; I ++) {RD (QQ [I]. s); RD (QQ [I]. e ); QQ [I]. s --; QQ [I]. e --; QQ [I]. id = I;} sort (QQ, QQ + Q, cmp); init (); int st = QQ [0]. s; int ed = QQ [0]. e; for (int I = st; I <= ed; I ++) {extend (a [I]-'A ');} for (int I = cnt-1; I> 0; I --) {ans [QQ [0]. id] + = qe [I]. val-qe [I]. pre-> val ;}for (int I = 1; I <Q; I ++) {// cout <QQ [I]. s <"" <QQ [I]. e <endl; // getchar (); if (QQ [I]. s! = QQ [I-1]. s) {init (); for (int j = QQ [I]. s; j <= QQ [I]. e; j ++) extend (a [j]-'A'); ans [QQ [I]. id] = solve ();} else {if (QQ [I]. e = QQ [I-1]. e) {ans [QQ [I]. id] = ans [QQ [I-1]. id];} else {for (int j = ed + 1; j <= QQ [I]. e; j ++) extend (a [j]-'A'); ans [QQ [I]. id] = solve () ;}} ed = QQ [I]. e ;}for (int I = 0; I <Q; I ++) {OT (ans [I]); puts ("") ;}} return 0 ;} # include <iostream> # Include <cstdio> # include <algorithm> # include <string> # include <cmath> # include <cstring> # include <queue> # include <set> # include <vector> # include <stack> # include <map> # include <iomanip> # define PI acos (-1.0) # define Max 2505 # define inf 1 <28 # define LL (x) (x <1) # define RR (x) (x <1 | 1) # define REP (I, s, t) for (int I = (s); I <= (t); ++ I) # define ll long # define mem (a, B) memset (a, B, size Of (a) # define mp (a, B) make_pair (a, B) # define PII pair <int, int> using namespace std; inline void RD (int & ret) {char c; do {c = getchar () ;}while (c <'0' | c> '9'); ret = c-'0 '; while (c = getchar ()> = '0' & c <= '9') ret = ret * 10 + (c-'0 ');} inline void OT (int a) {if (a> = 10) OT (a/10); putchar (a % 10 + '0 ');} struct SAM {SAM * pre, * next [26]; int val; void clear () {pre = 0; val = 0; Mem (next, 0) ;}}; SAM * root, * last, * cur; SAM qe [111111]; int cnt = 0; void init () {cnt = 0; root = last = & qe [cnt ++]; root-> clear ();} struct QU {int s, e, id;} QQ [100005]; void extend (int w) {SAM * p = last; SAM * np = & qe [cnt ++]; np-> clear (); np-> val = p-> val + 1; while (p &&! P-> next [w]) p-> next [w] = np, p = p-> pre; if (! P) {np-> pre = root;} else {SAM * q = p-> next [w]; if (p-> val + 1 = q-> val) {np-> pre = q;} else {SAM * nq = & qe [cnt ++]; nq-> clear (); memcpy (nq-> next, q-> next, sizeof (q-> next); nq-> val = p-> val + 1; nq-> pre = q-> pre; q-> pre = nq; np-> pre = nq; while (p & p-> next [w] = q) {p-> next [w] = nq; p = p-> pre ;}}last = np ;}# define N 100005 # define M 200 5 char a [M]; bool cmp (QU a, QU B) {if (. s = B. s) return. e <B. e; return. s <B. s;} int solve () {int sum = 0; for (int I = cnt-1; I> 0; I --) {sum + = qe [I]. val-qe [I]. pre-> val;} return sum;} int ans [N]; int main () {int T; cin> T; while (T --) {cin>; mem (ans, 0); int l = strlen (a); int Q; cin> Q; for (int I = 0; I <Q; I ++) {RD (QQ [I]. s); RD (QQ [I]. e); QQ [I]. s -- QQ [I]. e --; QQ [I]. id = I;} sort (QQ, QQ + Q, cmp); init (); int st = QQ [0]. s; int ed = QQ [0]. e; for (int I = st; I <= ed; I ++) {extend (a [I]-'A ');} for (int I = cnt-1; I> 0; I --) {ans [QQ [0]. id] + = qe [I]. val-qe [I]. pre-> val ;}for (int I = 1; I <Q; I ++) {// cout <QQ [I]. s <"" <QQ [I]. e <endl; // getchar (); if (QQ [I]. s! = QQ [I-1]. s) {init (); for (int j = QQ [I]. s; j <= QQ [I]. e; j ++) extend (a [j]-'A'); ans [QQ [I]. id] = solve ();} else {if (QQ [I]. e = QQ [I-1]. e) {ans [QQ [I]. id] = ans [QQ [I-1]. id];} else {for (int j = ed + 1; j <= QQ [I]. e; j ++) extend (a [j]-'A'); ans [QQ [I]. id] = solve () ;}} ed = QQ [I]. e ;}for (int I = 0; I <Q; I ++) {OT (ans [I]); puts ("") ;}} return 0 ;}