后缀自动机+LCT 【bzoj4545】 DQS的Trie
来源:互联网 发布:fetch.js官网 编辑:程序博客网 时间:2024/06/04 17:46
题目大意:
维护一个树,树的边上有一个字母,支持三个操作:
1、查询本质不同的子串的个数;
2、在树上的某一个节点长出一个新的子树;
3、查询某个串出现的次数。
题目分析:
对这棵树维护一个广义的后缀自动机。
对于1操作,只要维护每个节点的max_ len减去parent树上父节点的max_len,详见bzoj4516生成魔咒的题解;
对于3操作,则维护LCT进行链加即可,详见bzoj2555 SubString的题解。
所以说这题是4516和2555二合一啊O。O
注意:1操作要开long long
代码如下:
#include <cstdio>#include <cstring>#define N 1200000using namespace std;int id,n,m,opt,x,y,rt,sz;long long ans;char s[N],q[N<<1];int fir[N],nes[N<<1],v[N<<1],fa[N],tot=1,last_tot=1;void edge(int x,int y,char c){ v[++tot]=y; q[tot]=c; nes[tot]=fir[x]; fir[x]=tot; return;}#define edge(x,y,c) edge(x,y,c),edge(y,x,c)struct splay{ splay *ch[2],*fa; int sum,mark; splay(); void add_mark(int); void push_down(); void push_up(); int dir();}*null=new splay;splay :: splay(){ sum=mark=0; ch[1]=ch[0]=fa=null;}void splay :: add_mark(int v){ if(this==null) return; sum+=v; mark+=v;}void splay :: push_down(){ if(mark) { ch[0]->add_mark(mark); ch[1]->add_mark(mark); mark=0; }}void splay :: push_up(){ if(~dir()) fa->push_up(); push_down();}int splay :: dir(){ return fa->ch[0]==this?0:fa->ch[1]==this?1:-1;}void turn(splay *c,int d){ splay *y=c->ch[d^1]; c->ch[d^1]=y->ch[d]; if(y->ch[d]!=null) y->ch[d]->fa=c; y->ch[d]=c; y->fa=c->fa; int k; if(~(k=c->dir())) c->fa->ch[k]=y; c->fa=y;}void splaying(splay *c){ c->push_up(); int d; while(~(d=c->dir())) { if(d==c->fa->dir()) turn(c->fa->fa,d^1); turn(c->fa,d^1); }}void Access(splay *c){ splay *y=null; while(c!=null) { splaying(c); c->ch[1]=y; y=c; c=c->fa; } return;}void Cut(splay *x){ Access(x),splaying(x); x->ch[0]->fa=null; x->ch[0]=null;}void Link(splay *x,splay *y){ Cut(x); x->fa=y;}struct SAM{ SAM *son[26],*fa; int max_len; splay *tree; SAM(int _):max_len(_) { memset(son,0,sizeof(son)); fa=NULL; tree=new splay; }}*last[N],*root=new SAM(0);SAM* extend(SAM *last,int x){ SAM *p=last; SAM *np=new SAM(p->max_len+1); while(p && !p->son[x]) p->son[x]=np,p=p->fa; if(!p) np->fa=root; else { SAM *q=p->son[x]; if(q->max_len==p->max_len+1) np->fa=q; else { SAM *nq=new SAM(p->max_len+1); ans-=q->max_len-q->fa->max_len; q->tree->push_up(); nq->tree->sum=q->tree->sum; Link(q->tree,nq->tree); Link(nq->tree,q->fa->tree); nq->fa=q->fa; np->fa=nq; q->fa=nq; ans+=q->max_len-q->fa->max_len; ans+=nq->max_len-nq->fa->max_len; memcpy(nq->son,q->son,sizeof(nq->son)); for(;p && p->son[x]==q;p=p->fa) p->son[x]=nq; } } ans+=np->max_len-np->fa->max_len; Link(np->tree,np->fa->tree); Access(np->tree),splaying(np->tree); np->tree->add_mark(1); return np;}void dfs(int c){ for(int t=fir[c];t;t=nes[t]) { if(v[t]==fa[c]) continue; if(t<=last_tot) break; last[v[t]]=extend(last[c],q[t]-'a'); fa[v[t]]=c; dfs(v[t]); } return;}int query(char *s){ SAM *c=root; for(int i=0;s[i];i++) { if(!c->son[s[i]-'a']) return 0; c=c->son[s[i]-'a']; } c->tree->push_up(); return c->tree->sum;}int main(){ scanf("%d",&id); scanf("%d",&n); for(int i=1;i<n;i++) { scanf("%d%d%s",&x,&y,s); edge(x,y,s[0]); } last[1]=root; dfs(1); scanf("%d",&m); while(m--) { scanf("%d",&opt); switch(opt) { case 1: printf("%lld\n",ans); break; case 2: scanf("%d%d",&rt,&sz); last_tot=tot; for(int i=1;i<sz;i++) { scanf("%d%d%s",&x,&y,s); edge(x,y,s[0]); } dfs(rt); break; case 3: scanf("%s",s); printf("%d\n",query(s)); break; } } return 0;}
0 0
- 后缀自动机+LCT 【bzoj4545】 DQS的Trie
- [BZOJ4545]DQS的trie(广义后缀自动机+lct)
- 【BZOJ4545】DQS的trie
- BZOJ4545 DQS的trie
- [bzoj4545] DQS的trie
- bzoj 4545: DQS的trie (后缀自动机+LCT)
- bzoj2555 -- 后缀自动机+LCT
- BZOJ 4545: DQS的trie
- 【bzoj2555】SubString LCT+后缀自动机
- 2555: SubString 后缀自动机+LCT
- BZOJ2555:SubString 后缀自动机 LCT
- [BZOJ2555][LCT][后缀自动机]SubString
- 【bzoj2555】SubString 后缀自动机+LCT
- 后缀自动机 + LCT 【bzoj2555】SubString
- BZOJ2555 SubString 后缀自动机+LCT
- BZOJ 2555 SubString 后缀自动机+LCT
- bzoj 2555 SubString 后缀自动机 LCT
- bzoj 2555: SubString (LCT+后缀自动机)
- Myeclipse 8.5 集成 hibernate3.0连接mySQL数据库生成实体配置时报错:org.hibernate.exception.GenericJDBCException: Getting database metadata
- 01-编程工具-CMake使用教程
- 将博客搬至CSDN
- 配置Spring MVC 时报了个奇怪的错误: Error listenerStart Context [/SpringMvc] startup failed due to previous errors
- 关于JSTL/EL表达式在页面中无法解析的问题!
- 后缀自动机+LCT 【bzoj4545】 DQS的Trie
- 启动Myeclipse 9.1,刷新项目都会报Refreshing external folders NullPointerException错误。
- windows 7环境下配置oracle 11g 客户端
- Java基础学习笔记2
- HttpServletRequest对象方法的用法
- centOS x64系统上安装 oracle 11g R2 x64
- 调用其他文件py文件的函数
- 中国企业拿下“刷脸支付”项目
- 连接本地Oracle 11g时 ORA-12514:TNS:监听程序当前无法识别连接描述符中请求的服务