BZOJ 2555: SubString 动态树+后缀自动机
来源:互联网 发布:go语言高并发网络编程 编辑:程序博客网 时间:2024/06/04 19:47
首先,这是一道代码题,利用动态树维护后缀自动机的parent树,如果不是强制在线,可能会好写一点。
对于每个询问,找到被询问节点所在的right集合,集合大小即为答案。
注意,这里的LCT为有向的,写起来有些不一样。
#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>using namespace std;const int maxn = 3050000;int n,m,mask,T;char s[maxn];string chars;void gets(int mask){ scanf("%s",s); chars=s; 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; }}struct lct{ int w[maxn],ch[maxn][2],fa[maxn],tag[maxn],q[maxn]; bool rev[maxn]; bool isroot(int x){ return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x; } void add(int x,int y) { if(x) { w[x]+=y;tag[x]+=y; } } void pushdown(int x) { int l=ch[x][0],r=ch[x][1]; if(tag[x]) { add(l,tag[x]),add(r,tag[x]); tag[x]=0; } } void rotate(int x) { int y=fa[x],z=fa[y],l=ch[y][1]==x,r=l^1; if(!isroot(y)) ch[z][ch[z][1]==y]=x; fa[x]=z;fa[y]=x;fa[ch[x][r]]=y; ch[y][l]=ch[x][r],ch[x][r]=y; } void splay(int x){ int top=0;q[++top]=x; for(int i=x;!isroot(i);i=fa[i]) q[++top]=fa[i];//cout<<q[i]<<endl; for(int i=top;i;i--) pushdown(q[i]); while(!isroot(x)) { int y=fa[x],z=fa[y]; if(!isroot(y)) { if(ch[y][0]==x^ch[z][0]==y) rotate(x); else rotate(y); } rotate(x); } } void access(int x) { int t=0; while(x) { splay(x);ch[x][1]=t;t=x;x=fa[x]; } } void link(int x,int y){ fa[x]=y;access(y);splay(y);add(y,w[x]); } void cut(int x){ access(x);splay(x);add(ch[x][0],-w[x]); fa[ch[x][0]]=0;ch[x][0]=0; }}t;struct sam{ int last,cnt; int a[maxn][27],fa[maxn],mx[maxn]; sam(){ last=++cnt; } void insert(int c) { int p=last,np=last=++cnt;t.w[np]=1;mx[np]=mx[p]+1; while(!a[p][c]&&p) a[p][c]=np,p=fa[p]; if(!p) fa[np]=1,t.link(np,1); else { int q=a[p][c]; if(mx[p]+1==mx[q]) fa[np]=q,t.link(np,q); else { int nq=++cnt;mx[nq]=mx[p]+1; memcpy(a[nq],a[q],sizeof(a[q])); fa[nq]=fa[q]; t.link(nq,fa[q]); fa[np]=fa[q]=nq; t.cut(q);t.link(np,nq);t.link(q,nq); while(a[p][c]==q) a[p][c]=nq,p=fa[p]; } } } void build(){ scanf("%s",s); int l=strlen(s); for(int i=0;i<l;i++) insert(s[i]-'A'); } void add(){ gets(mask); int l=chars.length(); for(int i=0;i<l;i++) insert(chars[i]-'A'); } int query(){ gets(mask); int l=chars.length(),p=1; for(int i=0;i<l;i++) if(!(p=a[p][chars[i]-'A'])) return 0; t.splay(p); return t.w[p]; }} sam;char op[5];int main(){ scanf("%d",&T); sam.build(); while(T--) { scanf("%s",op); if(op[0]=='A') sam.add(); else { int ans=sam.query(); printf("%d\n",ans); mask^=ans; } } return 0;}
0 0
- BZOJ 2555: SubString 动态树+后缀自动机
- BZOJ 2555 SubString 后缀自动机
- 【后缀自动机】 BZOJ 2555 SubString
- BZOJ 2555 SubString 后缀自动机
- BZOJ 2555 SubString 后缀自动机+LCT
- bzoj 2555 SubString 后缀自动机 LCT
- bzoj 2555: SubString (LCT+后缀自动机)
- BZOJ 2555: SubString 后缀自动机+LCT
- [后缀自动机 LCT] BZOJ 2555 SubString
- bzoj 2555: SubString 后缀自动机+lct
- BZOJ 2555 SubString LCT 后缀自动机
- [BZOJ]2555 Substring 后缀自动机&LCT
- [后缀自动机][LCT] BZOJ 2555: SubString
- bzoj2555: SubString(后缀自动机+动态树)
- BZOJ 2555 Substring 后缀自动机+Link-Cut-Tree
- 2555: SubString 后缀自动机+LCT
- bzoj 2555(linkcuttree+后缀自动机)
- bzoj 3998(后缀自动机)
- TCP之异常关闭的意义
- 单例模式2
- 高级(复杂)指针的含义
- 如何自己做Zabbix数据导出功能(上)
- ReactNative 开源项目 --仿优购商城
- BZOJ 2555: SubString 动态树+后缀自动机
- Linux系统安装 OpenSSL两种方法
- TCP选项之SO_LINGER
- 获取数据库中的表以及数据条数
- Vue环境的搭建——新建项目——更新Vue版本
- Android应用优化小手册
- 使用cors解决跨域,ionic打包到android手机上发post请求报403错误
- 索引对排序的影响
- 大文件读取(超过内存)