[BZOJ]2555 Substring 后缀自动机&LCT
2017-12-12 16:04
495 查看
2555: SubString
Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 3115 Solved: 925
[Submit][Status][Discuss]
Description
懒得写背景了,给你一个字符串init,要求你支持两个操作
(1):在当前字符串的后面插入一个字符串
(2):询问字符串s在当前字符串中出现了几次?(作为连续子串)
你必须在线支持这些操作。
Input
第一行一个数Q表示操作个数第二行一个字符串表示初始字符串init
接下来Q行,每行2个字符串Type,Str
Type是ADD的话表示在后面插入字符串。
Type是QUERY的话表示询问某字符串在当前字符串中出现了几次。
为了体现在线操作,你需要维护一个变量mask,初始值为0
读入串Str之后,使用这个过程将之解码成真正询问的串TrueStr。
询问的时候,对TrueStr询问后输出一行答案Result
然后mask = mask xor Result
插入的时候,将TrueStr插到当前字符串后面即可。
HINT:ADD和QUERY操作的字符串都需要解压
Output
Sample Input
2A
QUERY B
ADD BBABBBBAAB
Sample Output
0HINT
40 % 的数据字符串最终长度 <= 20000,询问次数<= 1000,询问总长度<= 10000100 % 的数据字符串最终长度 <= 600000,询问次数<= 10000,询问总长度<= 3000000
新加数据一组--2015.05.20
Source
Ctsc模拟赛By 洁妹[Submit][Status][Discuss]
HOME Back
hh代码题...要求动态插入当然是用sam啦... 由sam里的parent的性质可以得到, 一个串的出现次数就是在sam里面跑出来到的节点的在parent树里的子树siz, 也就是到达点的 |right|. 由于要动态插入并且sam中会有砍掉par边, 加入par边的操作... 于是就想到用lct来维护啦. 这道题是有向图都不用makeroot... 虽然说是代码题但还是挺好写的, 也就100行.
需要注意的细节: 在访问一个节点的w一定要记得先把标记传下来, 要不然就会得到错误的答案。 话说样例查询不存在的串, 加了串后又不查询是有多水? 不过还是帮我查出re233. 一发AC一颗赛艇.
#include<bits/stdc++.h> using namespace std; const int maxn = 2e6 + 5; string chars; char ss[maxn]; int top, root, tot, mask, last, Q, ans; int dep[maxn], w[maxn], tag[maxn], c[maxn][2], fa[maxn], s[maxn], a[maxn][26], par[maxn]; inline void decr(int mask) { scanf("%s", ss); chars = ss; for (int j = 0; j < chars.length(); ++ j) { mask = (mask * 131 + j) % chars.length(); char t = chars[j]; chars[j] = chars[mask]; chars[mask] = t; } } inline bool isroot(const int &x) { return c[fa[x]][0] != x && c[fa[x]][1] != x; } inline void add(int x, int val) { if (x) w[x] += val, tag[x] += val; } inline void pushdown(int x) { if (tag[x]) { add(c[x][0], tag[x]), add(c[x][1], tag[x]); tag[x] = 0; } } inline void rotate(int x) { int y = fa[x], z = fa[y]; int l = (c[y][1] == x), r = l ^ 1; if (!isroot(y)) c[z][c[z][1] == y] = x; fa[x] = z, fa[y] = x, fa[c[x][r]] = y; c[y][l] = c[x][r], c[x][r] = y; } inline void splay(int x) { top = 0; s[++ top] = x; for (int i = x; !isroot(i); i = fa[i]) s[++ top] = fa[i]; for (int i = top; i; -- i) pushdown(s[i]); for (int f; !isroot(x); rotate(x)) if (!isroot(f = fa[x])) rotate((c[fa[f]][0] == f ^ c[f][0] == x) ? x : f); } inline void access(int x) { for (int t = 0; x; x = fa[x]) splay(x), c[x][1] = t, t = x; } inline void link(int x, int y) { fa[x] = y, access(y), splay(y), add(y, w[x]); } inline void cut(int x) { access(x), splay(x), add(c[x][0], -w[x]); fa[c[x][0]] = 0, c[x][0] = 0; } inline int query() { decr(mask); int len = chars.length(), p = 1; for (int j = 0; j < len; ++ j) if (!(p = a[p][chars[j] - 'A'])) return 0; splay(p); return w[p]; } inline void insert(int c) { int p = last, np = last = ++ tot; w[np] = 1, dep[np] = dep[p] + 1; while (p && !a[p][c]) a[p][c] = np, p = par[p]; if (!p) par[np] = root, link(np, root); else { int q = a[p][c]; if (dep[q] == dep[p] + 1) par[np] = q, link(np, q); else { int nq = ++ tot; dep[nq] = dep[p] + 1; par[nq] = par[q], link(nq, par[q]); memcpy(a[nq], a[q], sizeof(a[q])); par[np] = par[q] = nq; cut(q), link(q, nq), link(np, nq); while (a[p][c] == q) a[p][c] = nq, p = par[p]; } } } int main() { root = last = ++ tot; scanf("%d", &Q); scanf("%s", ss); for (register int i = 0; ss[i]; ++ i) insert(ss[i] - 'A'); for (register int i = 0; i < Q; ++ i) { scanf("%s", ss); if (ss[0] == 'A') { decr(mask); int len = chars.length(); for (int j = 0; j < len; ++ j) insert(chars[j] - 'A'); } else { ans = query(), mask ^= ans; printf("%d\n", ans); } } }
相关文章推荐
- bzoj 2555: SubString 后缀自动机+lct
- BZOJ 2555: SubString 后缀自动机+LCT
- BZOJ 2555 SubString LCT 后缀自动机
- 字符串(LCT,后缀自动机):BZOJ 2555 SubString
- [后缀自动机 LCT] BZOJ 2555 SubString
- BZOJ 2555: SubString 后缀自动机 LCT
- [BZOJ2555]SubString(后缀自动机+lct)
- 【后缀自动机+LCT】BZOJ2555[SubString]题解
- BZOJ2555 SubString 后缀自动机+LCT
- bzoj 2555 SubString 后缀自动机 LCT
- [BZOJ2555]SubString(后缀自动机+LCT)
- bzoj2555 SubString(后缀自动机+LCT)
- 【BZOJ2555】SubString 后缀自动机+LCT
- BZOJ 2555: SubString [后缀自动机 LCT]
- BZOJ2555 SubString 【后缀自动机 + LCT】
- BZOJ 2555 Substring(后缀自动机+LCT子树维护)
- bzoj 2555: SubString 后缀自动机+LCT
- BZOJ2555:SubString 后缀自动机 LCT
- 后缀自动机 + LCT 【bzoj2555】SubString
- BZOJ 2555 SubString 后缀自动机+LCT