题目: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. Maven的简介

    1 What? 1.1 Maven 简介Maven 是 Apache 软件基金会组织维护的一款自动化构建工具,专注服务于 Java 平台的项目构建和依赖管理.Maven 这个单词的本意是:专家,内行. ...

  2. SSL证书是“盾牌“还是”鸡肋“?

    德国联邦安全与IT办公室(BSI,职能相当于美国的国家安全与信息技术局)近日发布公告警告:网络攻击者冒充其发布了“关于Meltdown与Spectre攻击信息”的垃圾邮件,该邮件中包含指向修复补丁的页 ...

  3. 【JAVA学习】java虚拟机内存配置,-Xss256m -Xms512m -Xmx800m -XX:MaxPermSize=512m

    转自:https://blog.csdn.net/a503921892/article/details/39048737 配置tomcat服务器内存大小中的Xms.Xmx.PermSize.MaxPe ...

  4. throws和throw的用法例子以及检测和非检查异常

    throws E1,E2,E3 只是告诉程序这个方法可能会抛出这些个异常,方法的调用者可能要处理这些异常.而这些异常E1,E2,E3可能是该函数体产生的. 而throw是明确之处这个地方要抛出这个异常 ...

  5. Linux平台上DPDK入门指南

    1. 简介 本文档包含DPDK软件安装和配置的相关说明.旨在帮助用户快速启动和运行软件.文档主要描述了在Linux环境下编译和 运行DPDK应用程序,但是文档并不深入DPDK的具体实现细节. 1.1. ...

  6. 论Spark高手是怎样炼成的

    SPARK J大数据的处理怎么能变快一点,答案是请用spark,因为它是基于内存的,可以有效减少数据的落地次数.Spark性能超过Hadoop百倍,从多迭代批量处理出发,兼收并蓄数据仓库.流处理和图计 ...

  7. JavaScript tips —— 搞定闰年

    前言 处理时间时,常常要考虑用户的输入是否合法,其中一个很典型的场景就是平闰年的判断,网上其实有很多类似的算法,但是其实不必那么麻烦,下面我讲讲的我的思路. 规则 公元年数可被4整除为闰年,但是整百( ...

  8. 用java实现单链表

    对于一个单链表来说,要求有最基本的数据节点以及一些重要的方法. 方法应该有增删改查.定位.输出.获取链表长度.排序.链表读入.链表输出.下面是我用java写的单链表 public class List ...

  9. 十 web爬虫讲解2—Scrapy框架爬虫—Scrapy安装—Scrapy指令

    Scrapy框架安装 1.首先,终端执行命令升级pip: python -m pip install --upgrade pip2.安装,wheel(建议网络安装) pip install wheel ...

  10. null与""的区别

    两者的区别与 “数字0和没有不是同一种概念”是一个道理.null是空对象,""是空字符串null可以赋值给任何对象,而""就不行了,只能赋值给字符串对象如:St ...