原来还有序列自动机这种神奇的东西.
/* 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;
}