P4595 [COCI2011-2012#5] POPLOCAVANJE
阿新 • • 發佈:2020-11-23
P4595 [COCI2011-2012#5] POPLOCAVANJE
第一反應AC自動機,好傢伙,竟然只有 62.5MB 空間。那麼我直接放棄沒想法。那咱們先不考慮時間。
第一重優化時間:發現要匹配也就匹配最長的串,所以在fail樹上記一下fail能跳到的最長串。
發現每個串的詢問其實互相獨立,所以考慮可以分塊建AC自動機,然後直接分塊做完了。
/* Name: Author: Gensokyo_Alice Date: Description: */ #include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <vector> #include <queue> #include <stack> #include <cmath> #include <ctime> #include <map> #include <set> using namespace std; typedef int ll; const ll MAXN = 1e6+10; ll N, M, tot, tag[MAXN], tim, vis[MAXN], head[MAXN], cnt = -1, maxn[MAXN], ans[MAXN], sum; char ss[MAXN], st[MAXN]; struct nod { ll fail, cnt, nt[26]; } t[MAXN]; struct edge { ll nt, to; } E[MAXN]; void ins(char*, ll); void bfs(); void cha(); void add(ll, ll); void dfs(ll); void clear(ll); int main() { memset(head, -1, sizeof(head)); scanf("%d", &N); scanf("%s", ss+1); scanf("%d", &M); ll SIZ = sqrt(M); for (ll i = 1; i <= M; i += SIZ) { tot = 0; for (ll j = i; j < i + SIZ && j <= M; j++) { scanf("%s", st+1); ins(st, strlen(st+1)); } bfs();cha(); tim++; clear(0); tag[0] = tim; } for (ll i = 1; i <= N; i++) ans[i] += ans[i-1], sum += (ans[i] == 0); printf("%d\n", sum); return 0; } void cha() { ll now = 0; for (ll i = 1; i <= N; i++) { now = t[now].nt[ss[i]-'a']; ans[i+1] -= 1, ans[i-maxn[now]+1] += 1; } } void ins(char* tem, ll len) { ll now = 0; for (ll i = 1; i <= len; i++) { if (!t[now].nt[tem[i]-'a']) t[now].nt[tem[i]-'a'] = ++tot, clear(tot); now = t[now].nt[tem[i]-'a']; } t[now].cnt = len; } void clear(ll now) {if (tag[now] < tim) tag[now] = tim, maxn[now] = 0, t[now].cnt = 0, t[now].fail = 0, memset(t[now].nt, 0, sizeof(t[now].nt)); } void bfs() { queue <ll> q; q.push(0); while (!q.empty()) { ll nt = q.front(); q.pop(); for (ll i = 0; i < 26; i++) { ll son = t[nt].nt[i]; if (son) {q.push(son); if (!nt) continue; t[son].fail = t[t[nt].fail].nt[i];} else t[nt].nt[i] = t[t[nt].fail].nt[i]; } } for (ll i = 0; i <= tot; i++) head[i] = -1; cnt = -1; for (ll i = 1; i <= tot; i++) add(t[i].fail, i); dfs(0); } void dfs(ll n) { maxn[n] = max(maxn[n], t[n].cnt); for (ll i = head[n]; ~i; i = E[i].nt) { ll v = E[i].to; maxn[v] = maxn[n]; dfs(v); } } void add(ll x, ll y) { cnt++; E[cnt].to = y; E[cnt].nt = head[x]; head[x] = cnt; }