Topic Link Description
Gives a sequence of \ (n\) . Find the longest identical substring of this \ (n\) sequence.
Here, the same definition is: Two substrings of the same length and all elements of a string plus one number will become another string.
Ideas for reference: Hzwer. Law one: KMP
Enumerates the beginning of the answer string in the first string, with the remaining \ (n-1\) strings (kmp\).
Method two: Suffix array
The \ (n\) string is stitched together. Binary answer \ (len\), group \ (height\) ,\ (check\) whether there is a set number \ (\geq len\) and fall in \ (n\) In a different string.
Note : the \ (n-1\) delimiter between\ (n\) strings should use a different symbol.
The "Same" treatment method one
KMP, you can redefine the meaning of "= =".
Thought similar to HDU 4749 & POJ 3167 KMP deformation
Method Two: Differential codever. 1:kmp
#include <bits/stdc++.h>#define MAXN 1010using namespaceStdtypedef Long LongLL;intA[MAXN][MAXN], F[MAXN], M[MAXN];BOOLMatchintTintPintP2,intp1) {return!P1 | | T[p2]-t[p2-1]==p[p1]-p[p1-1]; }voidGetfail (intPintN) {f[0] = f[1] =0; for(inti =1; I < n; ++i) {intj = F[i]; while(J &&!match (p, p, I, j)) J = F[j]; F[i+1] = Match (p, p, I, j)? J+1:0; }}intKmpintTintPintMintN) {intj = f[0], ret =0; for(inti =0; I < m; ++i) { while(J &&!match (T, P, I, j)) J = F[j];if(Match (T, P, I, J)) ++j;if(j==n)returnN RET = MAX (ret, j); }returnRET;}intMain () {intN scanf"%d", &n); for(inti =0; I < n; ++i) {scanf ("%d", &m[i]); for(intj =0; J < M[i]; ++J) scanf ("%d", &a[i][j]); }intAns =0; for(inti =0; I < m[0]; ++i) {intLen = m[0]-i;if(Len < ans) Break; Getfail (a[0]+i, Len);intMinn = len; for(intj =1; J < N; ++J) minn = MIN (Minn, KMP (A[j], a[0]+i, M[j], m[0]-i)); ans = max (ans, Minn); } printf ("%d\n", ans);return 0;}
Ver. 2: Suffix array
#include <bits/stdc++.h>#define MAXN 1010#define MAXN (int) 1e7using namespaceStdtypedef Long LongLL;intWA[MAXN], WB[MAXN], WV[MAXN], WT[MAXN], H[MAXN], RK[MAXN], SA[MAXN], N, R[MAXN], ID[MAXN], L[MAXN], A[MAXN][MAXN], vis[ MAXN];BOOLflag[maxn];vector<int> v;BOOLcmpint* R,intAintBintL) {returnR[a] = = R[b] && r[a+l] = = R[b+l]; }voidInitint* R,int* SA,intNintm) {int* X=wa, *Y=WB, *t, I, J, p; for(i =0; I < m; ++i) Wt[i] =0; for(i =0; I < n; ++i) ++wt[x[i] = R[i]; for(i =1; I < m; ++i) Wt[i] + = wt[i-1]; for(i = n-1; I >=0; -i) sa[--wt[x[i]] = i; for(j =1, p =1; P < n; J <<=1, 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) Wt[i] =0; for(i =0; I < n; ++i) ++wt[wv[i]; for(i =1; I < m; ++i) Wt[i] + = wt[i-1]; for(i = n-1; I >=0; -i) sa[--wt[wv[i]] [y[i]; t = x, x = y, y = t, x[sa[0]] =0; for(P =1, i =1; I < n; ++i) X[sa[i] = cmp (y, sa[i], sa[i-1], j)? P-1: p++; } for(i =0; I < n; ++i) Rk[sa[i]] = i;intK =0; for(i =0; I < n-1; h[rk[i++]] = k) { for(k = k?--k:0, j = Sa[rk[i]-1]; R[i+k] = = R[j+k]; ++K); }}intCurBOOLOk (vector<int>& v) {++cur;if(V.size () <n)return false;intCNT =0; for(AutoX:V) {if(Flag[x])Continue;if(vis[id[x]]!=cur) ++cnt, vis[id[x]] = cur; }returnCnt==n;}BOOLCheckintLenintTOT) {BOOLCnt=0; for(inti =1; i < tot; ++i) {if(H[i] < Len) {if(CNT && OK (v))return true; V.clear (); CNT =true; } v.push_back (Sa[i]); }return false;}intMain () {inttot=0, m=0, X, le=1, ri=1010, ans=0; scanf"%d", &n); for(inti =0; I < n; ++i) {scanf ("%d", &l[i]); ri = Min (ri, l[i]-1); for(intj =0; J < L[i]; ++J) {scanf ("%d", &a[i][j]);if(j) m = Max (M, a[i][j]-a[i][j-1]); } } for(inti =0; I < n; ++i) { for(intj =1; J < L[i]; ++J) {R[tot] = A[i][j]-a[i][j-1]; id[tot++] = i; } R[tot] = ++m; Id[tot] = i; flag[tot++] =true; } R[tot-1] =0;intMN = r[0]; for(inti =1; I < tot-1; ++i) mn = min (r[i], MN); for(inti =0; I < tot-1; ++i) r[i]-= MN-1; M-= MN-1; Init (R, SA, tot, ++m); while(Le <= RI) {intMID = Le+ri>>1;if(Check (Mid, tot)) Ans=mid, Le=mid+1;ElseRi=mid-1; } printf ("%d\n", ans+1);return 0;}
Luogu 2463 [sdoi2008]sandy card KMP | | The longest common substring of a suffix array n strings