第一行两个整数N,M表示待检查的作文数量,和小强的标准作文库
的行数
接下来M行的01串,表示标准作文库
接下来N行的01串,表示N篇作文
N行,每行一个整数,表示这篇作文的Lo 值。
输入文件不超过1100000字节
注意:题目有改动,可识别的长度不小于90%即可,而不是大于90%
#include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> using namespace std; const int maxn = 1100010; struct Tsam{ struct sanode{ sanode *f, *ch[3]; int l; }pool[maxn * 2], *root, *tail; int tot; void add(int c, int len){ sanode *p = tail, *np = &pool[++ tot]; np->l = len; tail = np; for (; p && !p->ch[c]; p = p->f) p->ch[c] = np; if (!p) np->f = root; else if (p->ch[c]->l == p->l + 1) np->f = p->ch[c]; else{ sanode *q = p->ch[c], *r = &pool[++ tot]; *r = *q; r->l = p->l + 1; q->f = np->f = r; for (; p && p->ch[c] == q; p = p->f) p->ch[c] = r; } } void clear(){ // memset(pool, 0, sizeof(pool)); 去了这句话从1732ms变成了 852ms root = tail = &pool[tot = 1]; } void get_f(char *s, int len, int *f){ sanode *p = root; for (int i = 1, l = 0; i <= len; f[i ++] = l) if (p->ch[s[i] - '0']) l ++, p = p->ch[s[i] - '0']; else{ while (p && !p->ch[s[i] - '0']) p = p->f; if (!p) l = 0; else l = p->l + 1, p = p->ch[s[i] - '0']; } } }sam; int n, m; char ch[maxn]; void init(){ int k = 0; scanf("%d%d", &n, &k); sam.clear(); int tot = 0; for (int i = 1; i <= k; i ++){ scanf("%s", ch + 1); int len = strlen(ch + 1); for (int j = 1; j <= len; j ++) sam.add(ch[j] - '0', ++ tot); sam.add(2, ++ tot); } } int g[maxn], f[maxn], h[maxn]; bool check(int l){ int tt = 0, ww = -1; for (int i = 1; i <= m; i ++){ f[i] = f[i - 1]; if (i - l>= 0){ while (tt <= ww && f[i - l] - (i - l) >= f[h[ww]] - h[ww]) ww --; h[++ ww] = i - l; } while (tt <= ww && h[tt] < i - g[i]) tt ++; if (tt <= ww) f[i] = max(f[i], f[h[tt]] + i - h[tt]); } return f[m] >= m * 0.9 - (1e-9); } void solve(){ sam.get_f(ch, m, g); int tt = 0, ww = m, ans = 0; while (tt <= ww){ int mid = (tt + ww) / 2; if (check(mid)) tt = mid + 1, ans = mid; else ww = mid - 1; } printf("%d\n", ans); } void work(){ for (int i = 1; i <= n; i ++){ scanf("%s", ch + 1); m = strlen(ch + 1); solve(); } } int main(){ init(); work(); return 0; }