题链:

http://www.lydsy.com/JudgeOnline/problem.php?id=2555
题解:

后缀自动机+LCT
不难发现,对于输入的询问串,在自动机里trans后的到的状态的Right集合的大小就是答案。
那么后缀自动机本身就是支持在线添加的,问题就是如何维护好parent树,即如何维护好每个状态的Right集合。
那么Link-Cut-Tree就显然可以完成动态维护parent树的任务。
(这里是维护的一颗根固定的树,没有Beroot()等换根函数)

代码:

#include<bits/stdc++.h>
#define MAXN 600005
using namespace std;
int MASK;
struct LCT{
int size;
int ch[MAXN*3][2],fa[MAXN*3],lazy[MAXN*3],val[MAXN*3];
bool Who(int x){return ch[fa[x]][0]!=x;}
bool Isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
void Update(int x,int v){val[x]+=v; lazy[x]+=v;}
void Pushdown(int x){
if(!Isroot(x)) Pushdown(fa[x]);
if(!lazy[x]) return;
Update(ch[x][0],lazy[x]);
Update(ch[x][1],lazy[x]);
lazy[x]=0;
}
void Rotate(int x){
static int y,z,l1,l2;
y=fa[x]; z=fa[y];
l1=Who(y); l2=Who(x); fa[x]=z;
if(!Isroot(y)) ch[z][l1]=x;
fa[y]=x; fa[ch[x][l2^1]]=y;
ch[y][l2]=ch[x][l2^1]; ch[x][l2^1]=y;
}
void Splay(int x){
static int y; Pushdown(x);
for(;y=fa[x],!Isroot(x);Rotate(x)) if(!Isroot(y))
Rotate(Who(y)==Who(x)?y:x);
}
void Access(int x){
static int y;
for(y=0;x;y=x,x=fa[x])
Splay(x),ch[x][1]=y;
}
void Link(int x,int y){
Access(x); Splay(x); Update(x,val[y]); fa[y]=x;
}
void Cut(int x){
Access(x);
Splay(x);
Update(ch[x][0],-val[x]);
fa[ch[x][0]]=0; ch[x][0]=0;
}
int Query(int x){
Splay(x); return val[x];
}
}DT;
struct SAM{
int size,last;
int maxs[MAXN*3],trans[MAXN*3][26],parent[MAXN*3];
int Newnode(int a,int b){
++size; maxs[size]=a;
memcpy(trans[size],trans[b],sizeof(trans[b]));
return size;
}
void Extend(int x){
static int p,np,q,nq;
p=last; last=np=Newnode(maxs[p]+1,0);
for(;p&&!trans[p][x];p=parent[p]) trans[p][x]=np;
if(!p) parent[np]=1;
else{
q=trans[p][x];
if(maxs[p]+1!=maxs[q]){
nq=Newnode(maxs[p]+1,q);
parent[nq]=parent[q];
parent[q]=parent[np]=nq;
for(;p&&trans[p][x]==q;p=parent[p]) trans[p][x]=nq;
DT.Cut(q);
DT.Link(parent[nq],nq);
DT.Link(nq,q);
}
else parent[np]=q;
}
DT.val[np]=1;
DT.Link(parent[np],np);
}
void Reset(){
memset(trans[0],0,sizeof(trans[0]));
size=0; last=Newnode(0,0);
}
void Add(char *S){
for(int i=0;S[i];i++) Extend(S[i]-'A');
}
void Query(char *T){
static int p,ans; p=1;
for(int i=0;T[i];i++){
if(!trans[p][T[i]-'A']){
p=0; break;
}
p=trans[p][T[i]-'A'];
}
if(!p) ans=0;
else ans=DT.Query(p);
printf("%d\n",ans);
MASK^=ans;
}
}SUF;
void decode(char *S,int mask){
static int len; len=strlen(S);
for(int i=0;i<len;i++)
mask=(mask*131+i)%len,swap(S[i],S[mask]);
}
int main(){
static char S[MAXN*5],Type[10];
int Q; scanf("%d",&Q);
SUF.Reset();
scanf("%s",S);
SUF.Add(S);
while(Q--){
scanf("%s%s",Type,S);
decode(S,MASK);
if(Type[0]=='A') SUF.Add(S);
else SUF.Query(S);
}
return 0;
}

  

●BZOJ 2555 SubString的更多相关文章

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

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

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

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

  3. bzoj 2555 SubString(SAM+LCT)

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

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

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

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

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

  6. bzoj 2555: SubString

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

  7. 【刷题】BZOJ 2555 SubString

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

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

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

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

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

随机推荐

  1. jsonp处理

    def loads_jsonp(self,_jsonp): try: return json.loads(re.match(".*?({.*}).*",_jsonp,re.S).g ...

  2. Tornado 网站demo 三

    模板 修改index.py #!/usr/bin/env Python # coding=utf-8 import tornado.web import methods.readdb as mrd c ...

  3. WingIDE5.*注册破解方法

    WingIDE是Python程序语言设计的集成开发环境,具有语法标签高亮显示,命令自动完成和函数跳转列表等非常强大的功能.本文主要介绍WingIDE 5安装及注册破解方法. 1. WingIDE 5下 ...

  4. Flask Session 详解

    会话session ,允许你在不同请求 之间储存信息.这个对象相当于用密钥签名加密的 cookie ,即用户可以查看你的 cookie ,但是如果没有密钥就无法修改它. from flask impo ...

  5. Python内置函数(23)——dict

    英文文档: class dict(**kwarg) class dict(mapping, **kwarg) class dict(iterable, **kwarg) Return a new di ...

  6. Spring Security入门(3-8)Spring Security获取session中的UserDetail

  7. (java基础)Java输入输出流及文件相关

    字节流: 所有的字节输入输出都继承自InputStream和OutputStream,通常用于读取二进制数据,最基本单位为单个字节,如图像和声音.默认不使用缓冲区. FileInputStream和F ...

  8. 学习ASP.NET Core Razor 编程系列五——Asp.Net Core Razor新建模板页面

    学习ASP.NET Core Razor 编程系列目录 学习ASP.NET Core Razor 编程系列一 学习ASP.NET Core Razor 编程系列二——添加一个实体 学习ASP.NET ...

  9. 前端插件之Bootstrap Switch 选择框开关控制

    简介 Bootstrap Switch是一款轻量级插件,可以给选择框设置类似于开关的样式 它是依赖于Bootstrap的一款插件 下载 下载地址 在线引用 导入 因为它是依赖于Bootstrap的一款 ...

  10. spring mvc跨域(post)--filter方案

    import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.Http ...