BZOJ 2555 SubString 后缀自动机
2015-01-19 18:45
309 查看
题目大意:给出一个字符串,支持在线在字符串后面加一个字符串,查询一个字符串在串中出现过几次。
思路:如果不想写正解的话,这个题就是后缀自动机的简单应用。正解其实是LCT+SAM,但是时间比暴力慢一倍。。。
暴力就很简单了,正序建立后缀自动机,每次查询的时候找到位置直接输出size的值。注意两点,一个是分裂节点的时候,size也要复制过去。查询的时候发现找不到要return 0;
CODE:
思路:如果不想写正解的话,这个题就是后缀自动机的简单应用。正解其实是LCT+SAM,但是时间比暴力慢一倍。。。
暴力就很简单了,正序建立后缀自动机,每次查询的时候找到位置直接输出size的值。注意两点,一个是分裂节点的时候,size也要复制过去。查询的时候发现找不到要return 0;
CODE:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAX 4000010 using namespace std; struct Complex{ Complex* tranc[26],*father; int len,size; }mempool[MAX],*C = mempool,*last,*root,none,*nil = &none; Complex *NewComplex(int _) { C->len = _; C->size = 0; fill(C->tranc,C->tranc + 26,nil); C->father = nil; return C++; } void Initialize() { root = last = NewComplex(0); } inline void Add(int c) { Complex *np = NewComplex(last->len + 1),*p = last; for(; p != nil && p->tranc[c] == nil; p = p->father) p->tranc[c] = np; if(p == nil) np->father = root; else { Complex *q = p->tranc[c]; if(q->len == p->len + 1) np->father = q; else { Complex *nq = NewComplex(p->len + 1); memcpy(nq->tranc,q->tranc,sizeof(nq->tranc)); nq->father = q->father; np->father = q->father = nq; nq->size = q->size; for(; p != nil && p->tranc[c] == q; p = p->father) p->tranc[c] = nq; } } last = np; for(; np != root; np = np->father) ++np->size; } int asks; char s[MAX],opt[10]; inline void DecodeWithMask(int mask) { int length = strlen(s); for(int i = 0; i < length; ++i) { mask = (mask * 131 + i) % length; swap(s[i],s[mask]); } } inline int Ask() { Complex *now = root; int length = strlen(s); for(int i = 0; i < length; ++i) if(now->tranc[s[i] - 'A'] != nil) now = now->tranc[s[i] - 'A']; else return 0; return now->size; } int main() { Initialize(); scanf("%d%s",&asks,s); int length = strlen(s); for(int i = 0; i < length; ++i) Add(s[i] - 'A'); int mask = 0; for(int i = 1; i <= asks; ++i) { scanf("%s%s",opt,s); DecodeWithMask(mask); if(opt[0] == 'Q') { int last_ans = Ask(); printf("%d\n",last_ans); mask ^= last_ans; } else { length = strlen(s); for(int i = 0; i < length; ++i) Add(s[i] - 'A'); } } return 0; }
相关文章推荐
- 【bzoj2555】SubString 后缀自动机+LCT
- 【BZOJ-2555】SubString 后缀自动机 + LinkCutTree
- 【后缀自动机】 BZOJ 2555 SubString
- [后缀自动机][LCT] BZOJ 2555: SubString
- 【后缀自动机+LCT】BZOJ2555[SubString]题解
- BZOJ 2555: SubString 后缀自动机+LCT
- [BZOJ2555][LCT][后缀自动机]SubString
- bzoj2555 SubString(后缀自动机+LCT)
- [BZOJ]2555 Substring 后缀自动机&LCT
- BZOJ 2555 SubString 后缀自动机+LCT
- 【bzoj2555】SubString LCT+后缀自动机
- BZOJ2555 SubString 【后缀自动机 + LCT】
- BZOJ 2555: SubString 后缀自动机 LCT
- bzoj 2555: SubString 后缀自动机+lct
- [bzoj2555][后缀平衡树][后缀自动机]SubString
- bzoj 2555: SubString 后缀自动机+lct
- BZOJ2555:SubString (后缀自动机+(Splay+DFS序/LCT))
- bzoj 2555 SubString 后缀自动机 LCT
- [BZOJ2555]SubString(后缀自动机+LCT)
- [BZOJ2555]-SubString-后缀自动机+LCT维护parent树