您的位置:首页 > 其它

BZOJ4032【后缀自动机】【序列自动机】

2015-05-04 17:09 148 查看
原来还有序列自动机这种神奇的东西.

/* 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: