题目: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. 配置iptables实现本地端口转发的方法详解

    场景假如你在用 resin 调试一个 Web 程序,需要频繁地重启 resin.这个 Web 程序需要开在 80 端口上,而 Linux 限制 1024 以下的端口必须有 root 权限才能开启.但是 ...

  2. 并发-ConcurrentHashMap源码分析

    ConcurrentHashMap 参考: http://www.cnblogs.com/chengxiao/p/6842045.html https://my.oschina.net/hosee/b ...

  3. 初入spring boot(五 )websocket

    一.广播式 广播式即服务端有消息时,会将消息发送给所有连接了当前endpoint的浏览器 1.配置websocket,需要在配置类上使用@EnableWebSocketMessageBroker开启w ...

  4. 深入理解MR1与MR2的执行流程

    摘自:Tom White ,<Hadoop.The.Definitive.Guide.3rd.Edition> MR1 MR2

  5. 团体程序设计天梯赛 L2-018. 多项式A除以B(模拟)

    题意:给你A,B两个多项式,问你A/B的值:注意多项式给你的是每个式子的指数与系数:保留到一位小数,如果出现系数为0(保留后也是)的情况,请不要输出它,如果没有非系数为0的情况就输出特殊 题解:多项式 ...

  6. 使用IDEA将代码托管到GitHub步骤和错误解决

    一.下载并安装Git版本控制工具 下载地址:https://git-scm.com/downloads 注册GitHub账号:https://github.com/ 为什么托管到GitHub要下载Gi ...

  7. java XML解析

    package com.kpsh.myself; import java.io.File;import java.io.FileInputStream;import java.util.List; i ...

  8. yii2: 点击编辑后,左侧的连接(a.navtab)失效,变成在新窗口打开

    如:图一 使用a.navtab的时候,点击[自定义回复]->右侧列表,随便编辑一个,完成后 图二: 再点击,左侧的菜单,打开iframe就会失败,直接在新窗口打开.源代码如下: 造成这样的原因是 ...

  9. requirejs打包项目

    例子: https://github.com/AinneShen/requirejsExample 用requirejs为js和css添加版本,项目共用同一个config

  10. C#的静态构造函数.cctor

    静态构造函数操作的是类(而非其实例的)成员.静态构造函数(.cctor)的一些特点:1. 声明和定义形式上,只能有static一个修饰符,不能有任何修饰符和返回值(也不能有void).2. 不能被显示 ...