原来还有序列自动机这种神奇的东西.
/* I will wait for you*/ #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <algorithm> #include <iostream> #include <fstream> #include <vector> #include <queue> #include <deque> #include <map> #include <set> #include <string> #define make make_pair #define fi first #define se second using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int,int> pii; const int maxn = 4010; const int maxm = 1010; const int maxs = 26; const int inf = 0x3f3f3f3f; const int P = 1000000007; const double error = 1e-9; inline int read() { int x = 0, f = 1; char ch = getchar(); while (ch <= 47 || ch >= 58) f = (ch == 45 ? -1 : 1), ch = getchar(); while (ch >= 48 && ch <= 57) x = x * 10 + ch - 48, ch = getchar(); return x * f; } struct node { int x, y, val; } q[maxn * maxn]; char A[maxn], B[maxn]; int vis[maxn][maxn]; struct Suffix_Automation { int cnt; struct sam { sam *next[maxs], *fail; int val; }*root, *last, su[maxn]; void init() { cnt = 0; root = last = &su[cnt++]; } void insert(int x) { sam *now = &su[cnt++], *per = last; for (; per && !per -> next[x]; per = per -> fail) per -> next[x] = now; if (!per) now -> fail = root; else { sam *tmp = per -> next[x]; if (tmp -> val == per -> val + 1) now -> fail = tmp; else { sam *newx = &su[cnt++]; *newx = *tmp; newx -> val = per -> val + 1; tmp -> fail = now -> fail = newx; for (; per && per -> next[x] == tmp; per = per -> fail) per -> next[x] = newx; } } now -> val = last -> val + 1, last = now; } }Str_A, Str_B; struct Sequence_Automation { int cnt; struct qam { qam *next[maxs], *fail; }*root, *last[maxs + 1], su[maxn]; void init() { cnt = 0; last[maxs] = root = &su[cnt++]; } void insert(int x) { qam *now = &su[cnt++]; for (int i = 0; i <= maxs; i++) { qam *per = last[i]; for (; per && !per -> next[x]; per = per -> fail) per -> next[x] = now; } now -> fail = last[x], last[x] =now; } }Seq_A, Seq_B; int BFS1() { int l = 0, r = 1; q[0] = (node) {0, 0, 0}, vis[0][0] = 1; memset(vis, 0, sizeof vis); while (l != r) { node u = q[l++]; for (int i = 0; i < maxs; i++) { if (!Str_A.su[u.x].next[i]) continue; if (!Str_B.su[u.y].next[i]) return u.val + 1; int nx = Str_A.su[u.x].next[i] - Str_A.root; int ny = Str_B.su[u.y].next[i] - Str_B.root; if (!vis[nx][ny]) { vis[nx][ny] = 1; q[r++] = (node) {nx, ny, u.val + 1}; } } } return -1; } int BFS2() { int l = 0, r = 1; q[0] = (node) {0, 0, 0}, vis[0][0] = 1; memset(vis, 0, sizeof vis); while (l != r) { node u = q[l++]; for (int i = 0; i < maxs; i++) { if (!Str_A.su[u.x].next[i]) continue; if (!Seq_B.su[u.y].next[i]) return u.val + 1; int nx = Str_A.su[u.x].next[i] - Str_A.root; int ny = Seq_B.su[u.y].next[i] - Seq_B.root; if (!vis[nx][ny]) { vis[nx][ny] = 1; q[r++] = (node) {nx, ny, u.val + 1}; } } } return -1; } int BFS3() { int l = 0, r = 1; q[0] = (node) {0, 0, 0}, vis[0][0] = 1; memset(vis, 0, sizeof vis); while (l != r) { node u = q[l++]; for (int i = 0; i < maxs; i++) { if (!Seq_A.su[u.x].next[i]) continue; if (!Str_B.su[u.y].next[i]) return u.val + 1; int nx = Seq_A.su[u.x].next[i] - Seq_A.root; int ny = Str_B.su[u.y].next[i] - Str_B.root; if (!vis[nx][ny]) { vis[nx][ny] = 1; q[r++] = (node) {nx, ny, u.val + 1}; } } } return -1; } int BFS4() { int l = 0, r = 1; q[0] = (node) {0, 0, 0}, vis[0][0] = 1; memset(vis, 0, sizeof vis); while (l != r) { node u = q[l++]; for (int i = 0; i < maxs; i++) { if (!Seq_A.su[u.x].next[i]) continue; if (!Seq_B.su[u.y].next[i]) return u.val + 1; int nx = Seq_A.su[u.x].next[i] - Seq_A.root; int ny = Seq_B.su[u.y].next[i] - Seq_B.root; if (!vis[nx][ny]) { vis[nx][ny] = 1; q[r++] = (node) {nx, ny, u.val + 1}; } } } return -1; } int main() { scanf("%s%s", A + 1, B + 1); Str_A.init(), Seq_A.init(); Str_B.init(), Seq_B.init(); for (int i = 1; i <= strlen(A + 1); i++) { Str_A.insert(A[i] - 'a'); Seq_A.insert(A[i] - 'a'); } for (int i = 1; i <= strlen(B + 1); i++) { Str_B.insert(B[i] - 'a'); Seq_B.insert(B[i] - 'a'); } printf("%d\n", BFS1()); printf("%d\n", BFS2()); printf("%d\n", BFS3()); printf("%d\n", BFS4()); return 0; }