题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2555

要维护 right 集合的大小。因为 fa 会变,且 fa 构成一棵树,所以考虑用 LCT 来维护……

和平常写的 LCT 不太一样。因为要的值是原树上子树里的值,所以没有 makeroot ,splay 里不维护 splay 里的子树信息,只维护加法标记,表示 link 一下就给原树的自己到根的那条链上的所有点加了自己的值。cut 就是减掉自己的值。所以 query 或者 splay 的时候先把自己这棵 splay 里自己到根的路径 pshd 一遍,且没有 pshp 什么的。而且 link 时要区分两个点哪个是原树上的父亲。

不知怎么看出字符只有大写字母的。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=,K=,M=3e6+;
int cnt=,lst=,go[N][K],fa[N],l[N],mask;
int c[N][],pre[N],sta[N],top,sm[N],tg[N];
char ch[M];
void decodeWithMask(int n,int mask)
{
for(int i=;i<n;i++)
{
mask=(mask*+i)%n;
swap(ch[i],ch[mask]);
}
}
bool isroot(int x){return c[pre[x]][]!=x&&c[pre[x]][]!=x;}
void pshd(int x)
{
if(!tg[x])return;int ls=c[x][],rs=c[x][];
sm[ls]+=tg[x];tg[ls]+=tg[x];sm[rs]+=tg[x];tg[rs]+=tg[x];
tg[x]=;
}
void Pshd(int x)
{
sta[top=]=x;
for(;!isroot(x);x=pre[x])sta[++top]=pre[x];
for(int i=top;i;i--)pshd(sta[i]);
}
void rotate(int x)
{
int y=pre[x],z=pre[y];
if(!isroot(y))c[z][y==c[z][]]=x;
pre[x]=z;
int d=(x==c[y][]);
pre[c[x][!d]]=y; pre[y]=x;
c[y][d]=c[x][!d]; c[x][!d]=y;
}
void splay(int x)
{
Pshd(x);
while(!isroot(x))
{
int y=pre[x],z=pre[y];
if(!isroot(y))
{
if((y==c[z][])^(x==c[y][]))rotate(x);
else rotate(y);
}
rotate(x);
}
}
void access(int x)
{
for(int t=;x;splay(x),c[x][]=t,t=x,x=pre[x]);
}
void link(int x,int y)
{
pre[y]=x;access(x);splay(x);
sm[x]+=sm[y]; tg[x]+=sm[y];//tg:pre of x all added
}
void cut(int x)
{
access(x);splay(x);
sm[c[x][]]-=sm[x]; tg[c[x][]]-=sm[x];//tg:pre of x all declined
pre[c[x][]]=; c[x][]=;
}
void add(int w)
{
int p=lst,np=++cnt;lst=np;l[np]=l[p]+;sm[np]=;
for(;p&&!go[p][w];p=fa[p])go[p][w]=np;
if(!p)fa[np]=,link(,np);
else
{
int q=go[p][w];
if(l[q]==l[p]+)fa[np]=q,link(q,np);
else
{
int nq=++cnt;l[nq]=l[p]+;
cut(q);link(fa[q],nq);link(nq,q);link(nq,np);///
fa[nq]=fa[q];fa[q]=nq;fa[np]=nq;//after link&cut !
memcpy(go[nq],go[q],sizeof go[q]);
for(;go[p][w]==q;p=fa[p])go[p][w]=nq;
}
}
}
int query(int len)
{
int cr=;
for(int i=;i<len;i++)
{
if(!go[cr][ch[i]-'A'+])return ;
cr=go[cr][ch[i]-'A'+];
}
Pshd(cr); return sm[cr];
}
int main()
{
int Q;scanf("%d",&Q);scanf("%s",ch);
int n=strlen(ch);for(int i=;i<n;i++)add(ch[i]-'A'+);
char tch[];
while(Q--)
{
scanf("%s",tch);scanf("%s",ch);n=strlen(ch);
decodeWithMask(n,mask);
if(tch[]=='A')
{
for(int i=;i<n;i++)add(ch[i]-'A'+);
}
else
{
int d=query(n);printf("%d\n",d);
mask^=d;
}
}
return ;
}

bzoj 2555 SubString——后缀自动机+LCT的更多相关文章

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

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

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

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

  3. BZOJ 2555: SubString 后缀自动机_LCT

    很水的一道题,就是有些细节没注意到. 比如说将调试信息误以为是最终结果而多调了20分钟QAQ ..... 我们注意到,每新加一个节点,改变的是该节点沿着 Parent 走一直走到根节点. 对应的,在 ...

  4. bzoj 2555 SubString(SAM+LCT)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2555 [题意] 给定一个字符串,可以随时插入字符串,提供查询s在其中作为连续子串的出现 ...

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

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

  6. bzoj 5408: string 后缀自动机 + LCT

    联赛前练练码力. code: #include <vector> #include <cstdio> #include <cstring> #include < ...

  7. ●BZOJ 2555 SubString

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2555题解: 后缀自动机+LCT 不难发现,对于输入的询问串,在自动机里trans后的到的状态 ...

  8. bzoj 2555: SubString【后缀自动机+LCT】

    一直WA--找了半天错的发现居然是解密那里的mask其实是不能动的--传进去的会变,但是真实的那个不会变-- 然后就是后缀自动机,用LCT维护parent树了--注意不能makeroot,因为自动机的 ...

  9. 字符串(LCT,后缀自动机):BZOJ 2555 SubString

    2555: SubString Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 1620  Solved: 471 Description 懒得写背景了 ...

随机推荐

  1. BUG: scheduling while atomic 分析【转】

    本文转载自:https://blog.csdn.net/cfy_phonex/article/details/12090943 遇到一个典型的schedule问题.   <3>[26578 ...

  2. CocoaPods学习系列5——错误集锦

    这篇文章记录使用CocoaPods过程中遇到的一些错误. 1.error:include of non-modular header inside framework module 在自定义类库中,引 ...

  3. 浅谈 django Models中的跨表

    跨表操作在数据库操作非常常用,虽然其会降低读取数据的性能,但是它能节约数据在硬盘中的占用,优化数据表的结构和各自之间的关系. 在sql中,一般跨表需要用到 join 关键字 select * from ...

  4. imageView图片放大缩小及旋转

    imageView图片放大缩小及旋转 一.简介 二.方法 1)设置图片放大缩小效果 第一步:将<ImageView>标签中的android:scaleType设置为"fitCen ...

  5. centos下使用fdisk扩展分区容量大小

    硬盘空间为20G,VMware增加磁盘大小,需要再增加10G空间 扩展完后,重启系统,再次使用fdisk -l查看,会发现硬盘空间变大了: 重新创建分区,调整分区信息 本次实验主要对/dev/sda4 ...

  6. WPF中的平移缩放和矩阵变换(TranslateTransform、ScaleTransform、MatrixTransform)

    在WPF中的平移缩放都是通过RenderTransform这个类来实现这些效果的,在这个类中,除了平移和缩放还有旋转.扭曲变换.矩阵变换.这些都差不多的,都是坐标的变换. 这里我就先简单弄个平移和缩放 ...

  7. PL/SQL通过修改配置文件的方式实现数据库的连接

    http://jingyan.baidu.com/article/c74d600080632a0f6a595d80.html

  8. 用verilog来描述组合逻辑电路

    1,什么是组合逻辑电路? 逻辑电路在任何时刻产生的稳定的输出信号仅仅取决于该时刻的输入信号,而与过去的输入信号无关,即与输入信号作用前的状态无关,这样的电路称为组合逻辑电路. 上图给出了一个典型的数字 ...

  9. mysql的bin或者sbin目录可执行文件

    一. mysql服务和myql服务启动程序 1. mysqld mysqld就是mysql server,负责管理对mysql数据的访问. 当mysql server启动后,它会监听来自客户端的网络连 ...

  10. layui中实现上传图片压缩

    一.关于js上传图片压缩的方法,百度有很多种方法,这里我参考修改了一下: function photoCompress(file, w, objDiv) { var ready = new FileR ...