BZOJ 2555 SubString LCT 后缀自动机
2017-04-12 21:45
471 查看
题目大意:给出一个初始字符串,要求支持,在末尾添加一段字符串,查询一个串出现了几次,强制在线。
构造后缀自动机,一个串出现次数等于代表这个串的状态的right集合大小。
然而强制在线,right集合在添加之后会发生改变。
考虑添加一个字母时,只有产生的新状态的所有parent的right集合大小会加1,于是用LCT维护一下就好了。
构造后缀自动机,一个串出现次数等于代表这个串的状态的right集合大小。
然而强制在线,right集合在添加之后会发生改变。
考虑添加一个字母时,只有产生的新状态的所有parent的right集合大小会加1,于是用LCT维护一下就好了。
#include <cstdio> #include <cstring> #include <algorithm> #define N 3000005 using namespace std; namespace Link_Cut_Tree { struct Node { Node *ch[2],*pa; int dir() { return pa->ch[0]==this ? 0 : pa->ch[1]==this ? 1 : -1; } int val,add_mark; Node(); void add(int); void pushdown(); void* operator new(size_t) { static Node *mempool,*C; if(mempool==C) mempool=(C=new Node[1<<20])+(1<<20); return C++; } }*null=new Node(); Node :: Node() { ch[0]=ch[1]=pa=null; val=add_mark=0; } void Node :: add(int x) { val+=x; add_mark+=x; return ; } void Node :: pushdown() { if(add_mark) { ch[0]->add(add_mark); ch[1]->add(add_mark); add_mark=0; } return ; } void Rotate(Node* o,int d) { Node* k=o->ch[d^1]; int d2; o->ch[d^1]=k->ch[d], k->ch[d]->pa=o; k->ch[d]=o; //o->maintain(), k->maintain(); if(~(d2=o->dir())) o->pa->ch[d2]=k; k->pa=o->pa; o->pa=k; return ; } void To_pushdown(Node* o) { static Node* s ; int top=0; while(~(o->dir())) s[++top]=o, o=o->pa; s[++top]=o; while(top) s[top--]->pushdown(); return ; } void Splay(Node* o) { To_pushdown(o); int d; while(~(d=o->dir())) { if(o->pa->dir()==d) Rotate(o->pa->pa,d^1); Rotate(o->pa,d^1); } return ; } void Access(Node* o) { Node* p=null; while(o!=null) { Splay(o); o->ch[1]=p; p=o; o=o->pa; } return ; } void Cut(Node* x) { Access(x), Splay(x); x->ch[0]->pa=null; x->ch[0]=null; return ; } void Link(Node* x,Node* y) { Cut(x); x->pa=y; return ; } } #define LCT Link_Cut_Tree namespace Suffix_Automaton { struct Node { Node *ch[26],*pa; int val; LCT::Node* o; Node(int _val=0):val(_val),pa(NULL) { memset(ch,0,sizeof ch); o=new LCT::Node(); } void* operator new(size_t) { static Node *mempool,*C; if(mempool==C) mempool=(C=new Node[1<<20])+(1<<20); return C++; } }*root=new Node(0),*last=root; void Extend(char c) { int z=c-'A'; Node *p=last,*np=new Node(p->val+1); last=np; while(p && !p->ch[z]) p->ch[z]=np, p=p->pa; if(!p) { np->pa=root; LCT::Link(np->o,root->o); LCT::Access(np->o), LCT::Splay(np->o); np->o->add(1); return ; } Node* q=p->ch[z]; if(q->val==p->val+1) { np->pa=q; LCT::Link(np->o,q->o); LCT::Access(np->o), LCT::Splay(np->o); np->o->add(1); return ; } Node* nq=new Node(p->val+1); memcpy(nq->ch,q->ch,sizeof q->ch); LCT::Link(nq->o,q->pa->o); LCT::Link(q->o,nq->o); LCT::Link(np->o,nq->o); nq->pa=q->pa; q->pa=np->pa=nq; nq->o->val=q->o->val; while(p && p->ch[z]==q) p->ch[z]=nq, p=p->pa; LCT::Access(np->o), LCT::Splay(np->o); np->o->add(1); return ; } void Insert(char s[]) { int len=strlen(s); for(int i=0;i<len;i++) Extend(s[i]); return ; } int Query(char s[]) { Node* o=root; int len=strlen(s); for(int i=0;i<=len && o;i++) { if(i==len) return LCT::To_pushdown(o->o), o->o->val; o=o->ch[s[i]-'A']; } return 0; } } #define SAM Suffix_Automaton void decodeWithMask(char s[],int mask) { int len=strlen(s); for(int j=0;j<len;j++) { mask=(mask*131+j)%len; char t=s[j]; s[j]=s[mask]; s[mask]=t; } return ; } int main() { static char s ; int T; scanf("%d%s",&T,s); SAM::Insert(s); int mask=0; while(T--) { char mode[10]; scanf("%s%s",mode,s); decodeWithMask(s,mask); if(mode[0]=='Q') { int ans=SAM::Query(s); printf("%d\n",ans); mask^=ans; } else SAM::Insert(s); } return 0; }
相关文章推荐
- 【BZOJ2555】SubString 后缀自动机+LCT
- [BZOJ2555]-SubString-后缀自动机+LCT维护parent树
- BZOJ 2555 SubString 后缀自动机+LCT
- [BZOJ2555][LCT][后缀自动机]SubString
- BZOJ 2555: SubString [后缀自动机 LCT]
- bzoj 2555: SubString 后缀自动机+lct
- BZOJ 2555: SubString 后缀自动机+LCT
- bzoj 2555: SubString 后缀自动机+LCT
- [BZOJ]2555 Substring 后缀自动机&LCT
- BZOJ2555 SubString 后缀自动机+LCT
- BZOJ2555:SubString 后缀自动机 LCT
- [BZOJ2555]SubString(后缀自动机+LCT)
- 【bzoj2555】SubString 后缀自动机+LCT
- 【后缀自动机+LCT】BZOJ2555[SubString]题解
- 后缀自动机 + LCT 【bzoj2555】SubString
- BZOJ 2555 Substring(后缀自动机+LCT子树维护)
- 【bzoj2555】SubString LCT+后缀自动机
- bzoj 2555: SubString 后缀自动机+lct
- [BZOJ2555]SubString(后缀自动机+lct)
- 字符串(LCT,后缀自动机):BZOJ 2555 SubString