Description

懒得写背景了,给你一个字符串init,要求你支持两个操作
(1):在当前字符串的后面插入一个字符串
(2):询问字符串s在当前字符串中出现了几次?(作为连续子串)
你必须在线支持这些操作。

Input

第一行一个数Q表示操作个数
第二行一个字符串表示初始字符串init
接下来Q行,每行2个字符串Type,Str
Type是ADD的话表示在后面插入字符串。
Type是QUERY的话表示询问某字符串在当前字符串中出现了几次。
为了体现在线操作,你需要维护一个变量mask,初始值为0 

读入串Str之后,使用这个过程将之解码成真正询问的串TrueStr。
询问的时候,对TrueStr询问后输出一行答案Result
然后mask=maskxorResult
插入的时候,将TrueStr插到当前字符串后面即可。
HINT:ADD和QUERY操作的字符串都需要解压
长度 <= 600000,询问次数<= 10000,询问总长度<= 3000000
新加数据一组--2015.05.20

Output

 

Sample Input

2
A
QUERY B
ADD BBABBBBAAB

Sample Output

0

解题思路:

从后缀自动机构造的时候入手,因为Parent树是与pre指针直接相关,就在pre指针构造的时候快速维护Parent(LCT)。
剩下的就是两个模板堆叠,没什么思维含量。

代码:

 #include<cstdio>
#include<cstring>
#include<algorithm>
#define lll tr[spc].ch[0]
#define rrr tr[spc].ch[1]
#define ls ch[0]
#define rs ch[1]
class Unzip{
public:
void update(int lastans)
{
mask^=lastans;
return ;
}
void decode(int *a,int len)
{
int upg=mask;
for(int i=;i<=len;i++)
tmp[i-]=a[i];
for(int i=;i<len;i++)
{
upg=(upg*+i)%len;
std::swap(tmp[i],tmp[upg]);
}
for(int i=;i<=len;i++)
a[i]=tmp[i-];
return ;
}
private:
int tmp[];
int mask;
}U;
struct trnt{
int ch[];
int fa;
int is;
int lzt;
int wgt;
int wgti;
bool anc;
}tr[];
struct sant{
int tranc[];
int len;
int pre;
}s[];
int Q;
int siz;
int fin;
int lasans;
char tmp[];
int atp[];
bool whc(int spc)
{
return tr[tr[spc].fa].rs==spc;
}
void pushup(int spc)
{
tr[spc].wgt=tr[spc].wgti+tr[spc].is+tr[lll].wgt+tr[rrr].wgt;
return ;
}
void trr(int spc)
{
if(!spc)
return ;
std::swap(lll,rrr);
tr[spc].lzt^=;
return ;
}
void pushdown(int spc)
{
if(tr[spc].lzt)
{
trr(lll);
trr(rrr);
tr[spc].lzt=;
}
return ;
}
void recal(int spc)
{
if(!tr[spc].anc)
recal(tr[spc].fa);
pushdown(spc);
return ;
}
void rotate(int spc)
{
int f=tr[spc].fa;
bool k=whc(spc);
tr[f].ch[k]=tr[spc].ch[!k];
tr[spc].ch[!k]=f;
if(tr[f].anc)
{
tr[f].anc=;
tr[spc].anc=;
}else
tr[tr[f].fa].ch[whc(f)]=spc;
tr[spc].fa=tr[f].fa;
tr[f].fa=spc;
tr[tr[f].ch[k]].fa=f;
pushup(f);
pushup(spc);
return ;
}
void splay(int spc)
{
recal(spc);
while(!tr[spc].anc)
{
int f=tr[spc].fa;
if(tr[f].anc)
{
rotate(spc);
return ;
}
if(whc(spc)^whc(f))
rotate(spc);
else
rotate(f);
rotate(spc);
}
return ;
}
void access(int spc)
{
int lst=;
while(spc)
{
splay(spc);
tr[spc].wgti-=tr[lst].wgt;
tr[spc].wgti+=tr[rrr].wgt;
tr[rrr].anc=;
tr[lst].anc=;
rrr=lst;
pushup(spc);
lst=spc;
spc=tr[spc].fa;
}
return ;
}
void Mtr(int spc)
{
access(spc);
splay(spc);
trr(spc);
return ;
}
void split(int x,int y)
{
Mtr(x);
access(y);
splay(y);
return ;
}
void link(int x,int y)
{
split(x,y);
tr[x].fa=y;
tr[y].wgti+=tr[x].wgt;
pushup(y);
return ;
}
void cut(int x,int y)
{
split(x,y);
tr[x].fa=;
tr[y].ls=;
tr[x].anc=;
pushup(y);
return ;
}
void Insert(int c)
{
int nwp,nwq,lsp,lsq;
nwp=++siz;
tr[nwp].anc=;
tr[nwp].is=;
s[nwp].len=s[fin].len+;
for(lsp=fin;lsp&&!s[lsp].tranc[c];lsp=s[lsp].pre)
s[lsp].tranc[c]=nwp;
if(!lsp)
{
s[nwp].pre=;
link(nwp,);
}else{
lsq=s[lsp].tranc[c];
if(s[lsq].len==s[lsp].len+)
{
s[nwp].pre=lsq;
link(nwp,lsq);
}else{
nwq=++siz;
tr[nwq].anc=;
s[nwq]=s[lsq];
cut(s[lsq].pre,lsq);
link(s[nwq].pre,nwq);
s[nwq].len=s[lsp].len+;
s[nwp].pre=s[lsq].pre=nwq;
link(nwq,nwp);
link(nwq,lsq);
while(s[lsp].tranc[c]==lsq)
{
s[lsp].tranc[c]=nwq;
lsp=s[lsp].pre;
}
}
}
fin=nwp;
return ;
}
int Query(int root)
{
Mtr();
access(root);
return tr[root].wgti+tr[root].is;
}
int main()
{
fin=++siz;
tr[fin].anc=;
scanf("%d",&Q);
scanf("%s",tmp+);
int len=strlen(tmp+);
for(int i=;i<=len;i++)
Insert(tmp[i]-'A');
while(Q--)
{
scanf("%s",tmp);
if(tmp[]=='A')
{
scanf("%s",tmp+);
len=strlen(tmp+);
for(int i=;i<=len;i++)
atp[i]=tmp[i]-'A';
U.decode(atp,len);
for(int i=;i<=len;i++)
Insert(atp[i]);
}else{
scanf("%s",tmp+);
len=strlen(tmp+);
for(int i=;i<=len;i++)
atp[i]=tmp[i]-'A';
U.decode(atp,len);
int root=;
for(int i=;i<=len;i++)
{
root=s[root].tranc[atp[i]]; }
if(!root)
lasans=;
else
lasans=Query(root);
printf("%d\n",lasans);
U.update(lasans);
}
}
return ;
}

BZOJ2555: SubString(后缀自动机,LCT维护Parent树)的更多相关文章

  1. bzoj 2555 SubString —— 后缀自动机+LCT

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2555 建立后缀自动机,就可以直接加入新串了: 出现次数就是 Right 集合的大小,需要查询 ...

  2. luogu5212/bzoj2555 substring(后缀自动机+动态树)

    对字符串构建一个后缀自动机. 每次查询的就是在转移边上得到节点的parent树中后缀节点数量. 由于强制在线,可以用动态树维护后缀自动机parent树的子树和. 注意一个玄学的优化:每次在执行连边操作 ...

  3. 【BZOJ2555】SubString 后缀自动机+LCT

    [BZOJ2555]SubString Description 懒得写背景了,给你一个字符串init,要求你支持两个操作         (1):在当前字符串的后面插入一个字符串         (2 ...

  4. [Bzoj3676][Apio2014]回文串(后缀自动机)(parent树)(倍增)

    3676: [Apio2014]回文串 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 3396  Solved: 1568[Submit][Statu ...

  5. bzoj 3881 [Coci2015]Divljak——LCT维护parent树链并

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3881 对 S 建 SAM ,每个 T 会让 S 的 parent 树的链并答案+1:在 T ...

  6. bzoj 2555: SubString 后缀自动机+LCT

    2555: SubString Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 688  Solved: 235[Submit][Status][Dis ...

  7. bzoj 2555 SubString——后缀自动机+LCT

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2555 要维护 right 集合的大小.因为 fa 会变,且 fa 构成一棵树,所以考虑用 L ...

  8. BZOJ2555 SubString 【后缀自动机 + LCT】

    题目 懒得写背景了,给你一个字符串init,要求你支持两个操作 (1):在当前字符串的后面插入一个字符串 (2):询问字符串s在当前字符串中出现了几次?(作为连续子串) 你必须在线支持这些操作. 输入 ...

  9. BZOJ2555 SubString(后缀自动机+LCT)

    询问串放在SAM上不跳fail跑到的节点的|right|即为答案.用LCT维护parent树即可.可以直接维护子树信息,也可以转化为路径加.注意强制在线所使用的mask是作为参数传进去的. #incl ...

随机推荐

  1. Xcode加入应用图标以及启动界面

    寻找了许久的资料,记录下Xcode加入应用图标以及启动界面的学习笔记: 很实用的网址: 1.(苹果官网)Designing for iOS 2.iOS 8 人机交互指南 图标和图片的尺寸參考: 更加具 ...

  2. shrio 加密/编码

    在涉及到密码存储问题上,应该加密/生成密码摘要存储,而不是存储明文密码.比如之前的600w csdn账号泄露对用户可能造成很大损失,因此应加密/生成不可逆的摘要方式存储. 5.1 编码/解码 Shir ...

  3. 如何更改AD域安全策略-密码必须符合复杂性要求

    通常我们在域系统-管理工具上面是找不到“域安全策略”的,我们只能找到“本地安全策略”,而更改“本地安全策略”是不会对域产生任何的作用的.下面这个步骤教你如何找到“域安全策略” 1.Start(开始)– ...

  4. TCP简单说(下)

    本文在Creative Commons许可证下发布 TCP的RTT算法 从前面的TCP重传机制我们知道Timeout的设置对于重传非常重要. 设长了,重发就慢,丢了老半天才重发,没有效率,性能差: 设 ...

  5. 洛谷 P2614 计算器弹琴

    P2614 计算器弹琴 题目描述 总所周知,计算器可以拿来干很多它本不应该干的事情,比如写作文.(参看洛谷P2549) 小A发现了一个计算器的另一个隐藏功能——弹琴. http://www.bilib ...

  6. bzoj1084【SCOI2005】最大子矩阵

    1084: [SCOI2005]最大子矩阵 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 1946  Solved: 970 [Submit][id ...

  7. 【Tika基础教程之中的一个】Tika基础教程

    一.高速入门 1.Tika是一个用于文本解释的框架.其本身并不提供不论什么的库用于解释文本,而是调用各种各样的库,如POI,PDFBox等. 使用Tika.能够提取文件里的作者.标题.创建时间.正文等 ...

  8. Windows 操作系统与 .NET Framework

    Windos 2000 在单位的机房里好不easy才找到一台安装 Windows 2000 Server SP4 操作系统的server.这台硕果仅存的server到本月底也要退役了. Windows ...

  9. js插件---video.js如何使用

    js插件---video.js如何使用 一.总结 一句话总结:还是要去官方网站去看英文文档.快点把英语学好啊. 1.如何快速使用这些插件(比如video.js)? 直接百度这些js如何使用就可以了,这 ...

  10. rtsp和sdp协议简介

    RTSP是由Real network 和Netscape共同提出的如何有效地在IP网络上传输流媒体数据的应用层协议. 实时流协议(RTSP)建立并控制一个或几个时间同步的连续流媒体,如音频和视频.尽管 ...