您的位置:首页 > 其它

HDU - 6208 The Dominator of Strings HDU - 6208 AC自动机 || 后缀自动机

2017-09-17 21:40 471 查看
https://vjudge.net/problem/HDU-6208

首先可以知道最长那个串肯定是答案

然后,相当于用n - 1个模式串去匹配这个主串,看看有多少个能匹配。

普通kmp的话,每次都要O(mxLen)的复杂度肯定不行。考虑AC自动机,不说这个算法了都懂。

大概就是,询问主串的时候用Fail指针快速转移到LCP,然后就可以用字典树快速判断其是否一个模式串

可以知道判断过的可以标记下,不需要再判断了(听说很多人TLE在这里了,比赛的时候写歪了也TLE)

#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;
const int maxn = 1e5 + 2, N = 26;
struct SAM {
int mxCnt[maxn << 1], son[maxn << 1]
, fa[maxn << 1];
int root, last, DFN, t;
int create() {
++t;
mxCnt[t] = fa[t] = NULL;
for (int i = 0; i < N; ++i) son[t][i] = NULL;
return t;
}
void init() {
++DFN;
t = 0, root = 1;
last = create();
}
void addChar(int x, int _pos, int id) {
int p = last;
int np = create();
last = np;
mxCnt[np] = mxCnt[p] + 1;
for (; p && son[p][x] == NULL; p = fa[p]) son[p][x] = np;
if (p == NULL) {
fa[np] = root;
return;
}
int q = son[p][x];
if (mxCnt[q] == mxCnt[p] + 1) {
fa[np] = q;
return;
}
int nq = create();
for (int i = 0; i < N; ++i) son[nq][i] = son[q][i];
fa[nq] = fa[q], mxCnt[nq] = mxCnt[p] + 1;
fa[q] = nq, fa[np] = nq;
for (; p && son[p][x] == q; p = fa[p]) son[p][x] = nq;
}
bool is(string &str, int tt) {
int p = root;
for (int i = 0; i < tt; ++i) {
if (son[p][str[i] - 'a']) {
p = son[p][str[i] - 'a'];
} else return false;
}
return true;
}
} sam;
string str[maxn];
int tt[maxn];
char liu[maxn];
void work() {
sam.init();
int n;
scanf("%d", &n);
int id = 0, len = 0;
for (int i = 1; i <= n; ++i) {
scanf("%s", liu);
str[i] = string(liu);
tt[i] = strlen(str[i].c_str());
if (len < tt[i]) {
len = tt[i];
id = i;
}
}
for (int i = 0; i < len; ++i) {
sam.addChar(str[id][i] - 'a', i, 0);
}
for (int i = 1; i <= n; ++i) {
if (i == id) continue;
if (!sam.is(str[i], tt[i])) {
printf("No\n");
return;
}
}
printf("%s\n", str[id].c_str());
}

int main() {
#ifdef local
freopen("data.txt", "r", stdin);
//    freopen("data.txt", "w", stdout);
#endif
int t;
scanf("%d", &t);
while (t--) work();
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: