HDU 6208 The Dominator of Strings 读入挂+kmp / AC自动机
2017-09-20 09:32
381 查看
题目链接
题意
给定 n 个串,问是否存在一个串包含其它所有串。读入的问题
The total length of strings in each case has the limit of 100000. The limit is 30MB for the input file.
考虑将所有的串读到一整个串里,记录每个串在其中的开始位置和长度
注意:这种情况下,如果每个串末尾有
'\0',则开的长度不是 100000 而是 200000
法一:kmp 546ms
思路
找到最长的串作为主串,其它 n−1 个串作为模式串,跑 n−1 遍 kmpCode
#include <bits/stdc++.h> #define maxm 200010 const int BUF_SIZE = (int)1e4+10; using namespace std; int f[maxm]; char s[maxm], ans[maxm]; struct node { int beg, len; node(int _a=0, int _b=0) : beg(_a), len(_b) {} }nd[maxm]; struct fastIO { char buf[BUF_SIZE]; int cur; FILE *in, *out; fastIO() { cur = BUF_SIZE; in = stdin; out = stdout; } inline char nextChar() { if(cur == BUF_SIZE) { fread(buf, BUF_SIZE, 1, in); cur = 0; } return buf[cur++]; } inline int nextInt() { int x = 0; char c = nextChar(); while(!('0' <= c && c <= '9')) c = nextChar(); while('0' <= c && c <= '9') { x = x * 10 + c - '0'; c = nextChar(); } return x; } inline int nextString(char* s) { char c = nextChar(); int len = 0; while(!('a' <= c && c <= 'z')) c = nextChar(); while('a' <= c && c <= 'z') s[len++] = c, c = nextChar(); return len; } inline void printChar(char ch) { buf[cur++] = ch; if (cur == BUF_SIZE) { fwrite(buf, BUF_SIZE, 1, out); cur = 0; } } inline void printInt(int x) { if (x >= 10) printInt(x / 10); printChar(x % 10 + '0'); } inline void close() { if (cur > 0) { fwrite(buf, cur, 1, out); } cur = 0; } } IO; void getfail(char* P, int m) { f[0] = f[1] = 0; for (int i = 1; i < m; ++i) { int j = f[i]; while (j && P[j] != P[i]) j = f[j]; f[i+1] = P[j] == P[i] ? j+1 : 0; } } bool kmp(char* T, int n, char* P, int m) { getfail(P, m); int j = 0; for (int i = 0; i < n; ++i) { while (j && T[i] != P[j]) j = f[j]; if (T[i] == P[j]) ++j; if (j == m) return true; } return false; } int kas = 0; void work() { int n; n = IO.nextInt(); memset(s, 0, sizeof(s)); int mx = -1, p = -1, cur = 0; for (int i = 0; i < n; ++i) { int temp = cur; int len = IO.nextString(s+cur); nd[i] = node(cur, len); if (len > mx) mx = len, p = i; cur += len+1; } for (int i = 0; i < n; ++i) { if (p == i) continue; if (!kmp(s+nd[p].beg, nd[p].len, s+nd[i].beg, nd[i].len)) { printf("No\n"); return; } } printf("%s\n", s+nd[p].beg); } int main() { int T; T = IO.nextInt(); while (T--) work(); return 0; }
法二:AC自动机 2121ms
思路
对其他 n−1 个串建 AC自动机,拿最长的串在上面跑一遍。Code
#include <bits/stdc++.h> #define maxm 100010 const int BUF_SIZE = (int)1e4+10; using namespace std; int son[maxm][26], fail[maxm], cnt[maxm], tot; char s[maxm * 2]; struct node { int beg, len; node(int _a=0, int _b=0) : beg(_a), len(_b) {} }nd[maxm]; struct fastIO { char buf[BUF_SIZE]; int cur; FILE *in, *out; fastIO() { cur = BUF_SIZE; in = stdin; out = stdout; } inline char nextChar() { if(cur == BUF_SIZE) { fread(buf, BUF_SIZE, 1, in); cur = 0; } return buf[cur++]; } inline int nextInt() { int x = 0; char c = nextChar(); while(!('0' <= c && c <= '9')) c = nextChar(); while('0' <= c && c <= '9') { x = x * 10 + c - '0'; c = nextChar(); } return x; } inline int nextString(char* s) { char c = nextChar(); int len = 0; while(!('a' <= c && c <= 'z')) c = nextChar(); while('a' <= c && c <= 'z') s[len++] = c, c = nextChar(); return len; } inline void printChar(char ch) { buf[cur++] = ch; if (cur == BUF_SIZE) { fwrite(buf, BUF_SIZE, 1, out); cur = 0; } } inline void printInt(int x) { if (x >= 10) printInt(x / 10); printChar(x % 10 + '0'); } inline void close() { if (cur > 0) { fwrite(buf, cur, 1, out); } cur = 0; } } IO; void add(char* s, int len) { int p = 0; for (int i = 0; i < len; ++i) { if (son[p][s[i]-'a'] == -1) { cnt[++tot] = 0; for (int j = 0; j < 26; ++j) son[tot][j] = -1; son[p][s[i]-'a'] = tot; } p = son[p][s[i]-'a']; } ++cnt[p]; } void build() { queue<int> que; fail[0] = 0; for (int i = 0; i < 26; ++i) { if (son[0][i] == -1) son[0][i] = 0; else { fail[son[0][i]] = 0; que.push(son[0][i]); } } while (!que.empty()) { int x = que.front(); que.pop(); for (int i = 0; i < 26; ++i) { if (son[x][i] == -1) son[x][i] = son[fail[x]][i]; else { fail[son[x][i]] = son[fail[x]][i]; que.push(son[x][i]); } } } } int query(char* s, int len) { int p = 0, ret = 0; for (int i = 0; i < len; ++i) { p = son[p][s[i]-'a']; int temp = p; while (temp) { if (cnt[temp] == -1) break; ret += cnt[temp]; cnt[temp] = -1; temp = fail[temp]; } } return ret; } int kas = 0; void init() { memset(s, 0, sizeof(s)); cnt[tot = 0] = 0; for (int i = 0; i < 26; ++i) son[0][i] = -1; } void work() { init(); int n; n = IO.nextInt(); int mx = -1, p = -1, cur = 0; for (int i = 0; i < n; ++i) { int temp = cur; int len = IO.nextString(s+cur); nd[i] = node(cur, len); if (len > mx) mx = len, p = i; cur += len+1; add(s+nd[i].beg, nd[i].len); } build(); if (query(s+nd[p].beg, nd[p].len) == n) printf("%s\n", s+nd[p].beg); else printf("No\n"); } int main() { int T; T = IO.nextInt(); while (T--) work(); return 0; }
相关文章推荐
- hdu 6208 The Dominator of Strings 后缀自动机 LCS
- HDU 6208:The Dominator of Strings(字符串匹配)
- hdu 6208 The Dominator of Strings 后缀自动机 LCS
- hdu 6208 The Dominator of Strings 后缀自动机 LCS
- hdu 6208 The Dominator of Strings 后缀自动机 LCS
- hdu 6208 The Dominator of Strings 后缀自动机 LCS
- HDU 6208 The Dominator of Strings
- hdu 6208 The Dominator of Strings
- hdu 6208 The Dominator of Strings 后缀自动机 LCS
- 【KMP算法】The Dominator of Strings HDU - 6208
- hdu 6208 The Dominator of Strings 后缀自动机 LCS
- HDU 6208 The Dominator of Strings (字符串find函数暴力过)
- hdu 6208 The Dominator of Strings
- hdu 6208 The Dominator of Strings 后缀自动机 LCS
- HDU 6208 The Dominator of Strings (SAM)
- HDU 6208 The Dominator of Strings
- HDU 6208 The Dominator of Strings (AC自动机)
- hdu 6208 The Dominator of Strings 后缀自动机 LCS
- HDU 6208 The Dominator of Strings [AC自动机]
- HDU - 6208 The Dominator of Strings (2017 ACM-ICPC 亚洲区 (青岛赛区) 网络赛 1003)