Http://www.lydsy.com/JudgeOnline/problem.php? Id = 2754
Sa multi-template matching, complexity O (len1 + Log (len2), len1 for the search string length, len2 for the template String Length
# Include <iostream> # include <cstdio> # include <cstdlib> # include <cmath> # include <queue> # include <algorithm> # include <vector> # include <cstring> # include <stack> # include <cctype> # include <utility> # include <map> # include <string> # include <climits> # include <set> # include <string> # include <sstream> # include <utility> # include <ctime> # include <bitset> Using STD:: priority_queue; Using STD: vector; Using STD :: Swap; Using STD: Stack; Using STD: sort; Using STD: Max; Using STD: min; Using STD: pair; Using STD: map; using STD: string; Using STD: CIN; Using STD: cout; Using STD: Set; Using STD: queue; Using STD: string; Using STD :: stringstream; Using STD: make_pair; Using STD: Getline; Using STD: greater; Using STD: Endl; Using STD: multimap; Using STD: deque; using STD: unique; Using STD: lower_bound; Using STD: random_shuffle; Using STD: bitset; Using STD: upper_bound; typedef long ll; typedef unsigned long ull; typedef pair <int, int> pair; typedef multimap <int, int> MMAP; typedef ll ty; typedef long double lf; const int maxn (150010); const int maxm (100010); const int MaxE (100010 ); const int maxk (6); const int hsize (31313); const int sigma_size (26); const int maxh (19); const int INFI (INT_MAX-1)> 1 ); const ull base (31); con St ll Lim (10000000); const int inv (-10000); const int Mod (20100403); const double EPS (1e-7); const lf Pi (ACOs (-1.0 )); template <typename T> void checkmax (T & A, t B) {If (B> A) A = B;} template <typename T> void checkmin (T &, t B) {If (B <A) A = B;} template <typename T> T ABS (const T & A) {return a <0? -A: A;} struct SA {int s [maxn]; int SA [maxn], T1 [maxn], T2 [maxn], CNT [maxn], Len, M; void Init (int tl, int TM = 128) // TL indicates the length of the original string, and TM indicates the number of character sets {Len = TL; M = TM; int * P1 = T1; int * P2 = t2; For (INT I = 0; I <m; ++ I) CNT [I] = 0; For (INT I = 0; I <= Len; ++ I) ++ CNT [P1 [I] = s [I]; for (INT I = 1; I <m; ++ I) CNT [I] + = CNT [I-1]; for (INT I = Len; I> = 0; -- I) SA [-- CNT [P1 [I] = I; int temp = 1; for (int K = 1; temp <= Len; K <= 1) {temp = 0; For (INT I = len-k + 1; I <= Len; ++ I) p2 [temp ++] = I; for (INT I = 0; I <= Len; ++ I) if (SA [I]> = K) p2 [temp ++] = sa [I]-K; For (INT I = 0; I <m; ++ I) CNT [I] = 0; for (INT I = 0; I <= Len; ++ I) ++ CNT [P1 [P2 [I]; for (INT I = 1; I <m; + + I) CNT [I] + = CNT [I-1]; for (INT I = Len; I> = 0; -- I) sa [-- CNT [P1 [P2 [I] = P2 [I]; swap (P1, P2); temp = 1; p1 [SA [0] = 0; For (INT I = 1; I <= Len; ++ I) P1 [SA [I] = P2 [SA [I-1] = P2 [SA [I] & p2 [SA [I-1] + k] = P2 [SA [I] + k]? Temp-1: temp ++; M = temp;} int rank [maxn], height [maxn]; void getheight () {int K = 0; For (INT I = 0; I <= Len; ++ I) rank [SA [I] = I; for (INT I = 0; I <Len; ++ I) {If (k) -- k; Int J = sa [rank [I]-1]; while (s [I + k] = s [J + k]) ++ K; height [rank [I] = K ;}} int log [maxn]; int table [maxh] [maxn]; void initlog () {log [0] =-1; for (INT I = 1; I <maxn; ++ I) log [I] = (I & (I-1 ))? Log [I-1]: log [I-1] + 1;} void initrmq () {for (INT I = 1; I <= Len; ++ I) table [0] [I] = height [I]; for (INT I = 1; (1 <I) <= Len; ++ I) for (Int J = 1; j + (1 <I)-1 <= Len; ++ J) table [I] [J] = min (Table [I-1] [J], table [I-1] [J + (1 <(I-1)]);} int LCP (int A, int B) {A = rank [a]; B = rank [B]; If (A> B) Swap (A, B ); + + A; int temp = log [B-A + 1]; return min (Table [temp] [a], table [temp] [B-(1 <temp) + 1]);} int find (int * t, int Tlen) // multi-template match, template string, complexity O (tlen + Log (LEN) for each query {// note that initialization is required before searching, four functions: int L = 0, r = Len + 1, max_match = 0, ANS = Len; while (L <r) {int mid = (L + r)> 1; int Ts = sa [Mid]; int temp = LCP (TS, ANS); If (temp <max_match) {If (T [temp] <s [TS + temp]) r = mid; else l = Mid + 1 ;} else {While (max_match <tlen & T [max_match] = s [TS + max_match]) ++ max_match; If (max_match> = tlen) // return mid after matching is completed; if (T [max_mat Ch] <s [TS + max_match]) r = mid; else l = Mid + 1; ans = ts ;}} return-1; // no matching string found} SA; int hash [maxn]; int vis [maxn]; int arr [maxn]; int count [maxn]; int main () {int n, m; while (~ Scanf ("% d", & N, & M) {int L1 = 0, L2; int divi = 10001; For (INT I = 0; I <N; ++ I) {count [I] = 0; vis [I] =-1;} int Tn = N * 2; for (INT I = 0; I <tn; ++ I) {if (I) {SA. s [L1] = ++ divi; ++ L1;} scanf ("% d", & l2); For (Int J = 0; j <L2; ++ J) {scanf ("% d", SA. S + l1 + J); ++ SA. s [L1 + J]; hash [L1 + J] = I> 1;} SA. s [L1 + L2] = 0; l1 + = L2;} SA. init (L1, 50010); SA. getheight (); SA. initlog (); SA. initrmq (); For (INT I = 0; I <m; ++ I) {scanf (" % D ", & l2); For (Int J = 0; j <L2; ++ J) {scanf (" % d ", arr + J ); ++ arr [J];} int ind = sa. find (ARR, L2); int CNT = 0; If (IND! =-1) {int th = hash [SA. Sa [ind]; If (vis [th]! = I) {++ count [th]; vis [th] = I; ++ CNT ;}for (Int J = ind; SA. height [J]> = L2; -- j) {th = hash [SA. sa [J-1]; If (vis [th]! = I) {++ count [th]; vis [th] = I; ++ CNT ;}}for (Int J = ind + 1; SA. height [J]> = L2; ++ J) {th = hash [SA. sa [J]; If (vis [th]! = I) {++ count [th]; vis [th] = I; ++ CNT ;}} printf ("% d \ n", CNT );} for (INT I = 0; I <n; ++ I) {if (I) printf (""); printf ("% d", Count [I]);} printf ("\ n");} return 0 ;}