SAM+LCT维护parent tree版本

虽然说子树维护那套理论需要ETT

不过parent tree的根是固定的,所以用lct加一些奇怪的乱搞就行了

//随手拖个SAM的板子和LCT的板子,然后再加几句话就写完了【手动滑稽

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#define ll long long
#define N 1200006 using namespace std;
struct LinkCutTree{
#define ls(a) (t[a].c[0])
#define rs(a) (t[a].c[1])
struct LCTnode{
int c[2],fa;
int sum,tag;
} t[N];
void newnode(int x,int value){
ls(x)=rs(x)=t[x].fa=t[x].tag=0;
t[x].sum=value;
}
void Add(int x,int delta){
if (!x) return;
t[x].sum+=delta;t[x].tag+=delta;
}
int f(int x){return (ls(t[x].fa)!=x)*(1-2*(rs(t[x].fa)!=x));}
void PushDown(int x){
if (t[x].tag){
Add(ls(x),t[x].tag);
Add(rs(x),t[x].tag);
t[x].tag=0;
}
}
void rotate(int x){
int y=t[x].fa,z=t[y].fa,k=f(x),fz=f(y);
if (fz>=0) t[z].c[fz]=x;
t[y].c[k]=t[x].c[k^1];t[x].c[k^1]=y;
t[t[y].c[k]].fa=y;t[x].fa=z;t[y].fa=x;
}
int stack[N],top;
void splay(int x){
top=0;stack[top++]=x;
for (int i=x;f(i)>=0;i=t[i].fa) stack[top++]=t[i].fa;
while (top) PushDown(stack[--top]);
for (;f(x)>=0;rotate(x))
if (f(t[x].fa)==f(x)) rotate(t[x].fa);
else if (f(t[x].fa)>=0) rotate(x);
}
void access(int x){
for (int son=0;x;son=x,x=t[x].fa)
splay(x),rs(x)=son;
}
void link(int u,int f){
access(f);splay(f);Add(f,t[u].sum);
t[u].fa=f;
}
void cut(int u){
access(u);splay(u);Add(ls(u),-t[u].sum);
ls(u)=t[ls(u)].fa=0;
}
int getsum(int u){
splay(u);return t[u].sum;
}
} pt; struct SAM{
struct SAMnode{
int par,mx,go[26];
SAMnode(){}
SAMnode(int _mx):par(0),mx(_mx){
memset(go,0,sizeof(go));
}
} t[N];
int last,size;
int newnode(int _mx,int value){
t[++size]=SAMnode(_mx);
pt.newnode(size,value);
return size;
}
void clear(){size=0;last=newnode(0,0);}
void extend(char c){
c-='A';
int p=last,np=newnode(t[p].mx+1,1);
for (;p&&!t[p].go[c];p=t[p].par) t[p].go[c]=np;
if (!p) t[np].par=1,pt.link(np,1);
else{
int q=t[p].go[c];
if (t[p].mx+1==t[q].mx) t[np].par=q,pt.link(np,q);
else{
int nq=newnode(t[p].mx+1,0);
memcpy(t[nq].go,t[q].go,sizeof(t[q].go));
t[nq].par=t[q].par;pt.link(nq,t[q].par);
t[np].par=nq;pt.link(np,nq);
pt.cut(q);t[q].par=nq;pt.link(q,nq);
for (;p&&t[p].go[c]==q;p=t[p].par) t[p].go[c]=nq;
}
}
last=np;
}
int solve(char *s){
int p=1;
for (int i=0;p&&s[i];++i) p=t[p].go[s[i]-'A'];
if (!p) return 0;
return pt.getsum(p);
}
} sam; void decode(char *s,int mask){
int l=strlen(s);
for (int i=0;i<l;++i){
mask=(mask*131+i)%l;
swap(s[i],s[mask]);
}
} char st[N],op[10];
int main(){
int Q;scanf("%d%s",&Q,st);
sam.clear();
for (int i=0;st[i];++i) sam.extend(st[i]);
int mask=0,res;
while (Q--){
scanf("%s%s",op,st);
decode(st,mask);
if (op[0]=='Q'){
printf("%d\n",res=sam.solve(st));
mask^=res;
}
else for (int i=0;st[i];++i) sam.extend(st[i]);
}
return 0;
}

  

bzoj2555: SubString的更多相关文章

  1. BZOJ2555 SubString【SAM + Link Cut Tree】

    BZOJ2555. SubString 要求在线询问一个串在原串中出现的次数,并且可以在原串末尾添加字符串 如果没有修改的话,考虑建出\(parent\)树之后统计每个\(endpos\)节点的\(r ...

  2. [BZOJ2555]SubString LCT+后缀自动机

    2555: SubString Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 3253  Solved: 975[Submit][Status][Di ...

  3. BZOJ2555——SubString

    0.题目很短,就不概括了 给你一个字符串init,要求你支持两个操作 (1):在当前字符串的后面插入一个字符串 (2):询问字符串s在当前字符串中出现了几次?(作为连续子串) 你必须在线支持这些操作. ...

  4. 2019.03.01 bzoj2555: SubString(sam+lct)

    传送门 题意简述: 要求在线支持两个操作 (1):在当前字符串的后面插入一个字符串 (2):询问字符串s在当前字符串中出现了几次?(作为连续子串) 思路: 考虑用lctlctlct来动态维护samsa ...

  5. bzoj2555: SubString sam+lct

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

  6. bzoj2555 substring(LCT 后缀自动机)

    /* 动态求right集合的大小 LCT维护parent树即可 注意 由于树是有向的不会换根并且每次操作单一, 于是不需要维护子树和(写起来很麻烦) 直接打标记修改即可 */ #include< ...

  7. bzoj千题计划285:bzoj2555: SubString

    http://www.lydsy.com/JudgeOnline/problem.php?id=2555 后缀自动机,用LCT维护parent树 一个串的出现次数 = parent 树 上 其所在状态 ...

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

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

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

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

随机推荐

  1. CentOS 6.6安装Xtrabackup RPM提示缺少libev.so.4()

    在CentOS Release 6.6安装percona-xtrabackup-2.3.4时,遇到下面错误信息 rpm -ivh percona-xtrabackup-2.3.4-1.el6.x86_ ...

  2. Write on ……… failed: 112(failed to retrieve text for this error. Reason: 15105)

    早上检查数据库的备份邮件时,发现一台Microsoft SQL Server 2008 R2 (SP2)数据库的Maintenance Report有错误 在SSMS里面执行Exec YourSQLD ...

  3. 从零自学Hadoop(17):Hive数据导入导出,集群数据迁移下

    阅读目录 序 将查询的结果写入文件系统 集群数据迁移一 集群数据迁移二 系列索引 本文版权归mephisto和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作. 文章是哥(mephis ...

  4. nova-compute 部署 instance 详解 - 每天5分钟玩转 OpenStack(28)

    本节讨论 nova-compute,并详细分析 instance 部署的全过程. 先给大家道个歉:今天这篇文章的篇幅比以往要多一些,本来想分两次发,但考虑到文章的完整和系统性,还是一次发了出来,这次可 ...

  5. C#如何使用Soap协议调用WebService?

    WebService是什么?它的作用? WebService是一个平台独立.低耦合的.自包含的.基于可编程的可使用xml描述.调用的web应用程序,用于开发分布式的交互式的应用程序. Soap是什么? ...

  6. 无需FQ,自建本地CDN,秒上StackOverFlow!

    StackOverflow是一个面向程序员的技术问答平台.可是在不FQ的情况下,浏览StackOverflow是一件让人极不舒服的事情,常常需要等待数十秒页面才慢慢显示出来.本文我教大家一种能够流畅地 ...

  7. 编译软件基础知识(2/2) via LinuxSir

    首先说下/etc/ld.so.conf: 这个文件记录了编译时使用的动态链接库的路径. 默认情况下,编译器只会使用/lib和/usr/lib这两个目录下的库文件 如果你安装了某些库,比如在安装gtk+ ...

  8. [Django]Django1.8修改MySQL已存在表的问题?

    前言:django1.8版本出现这种问题,关于标题不好命令,直接看正文问题描述! 问题描述: 在已经生成了models.py中表的情况下,更改了modes.py中的表,但是syncdb不起作用报错.于 ...

  9. java设计模式之组合模式

    组合模式 组合模式,将对象组合成树形结构以表示“部分-整体”的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性.掌握组合模式的重点是要理解清楚 “部分/整体” 还有 ”单个对象“ 与 & ...

  10. 【2016-10-31】【坚持学习】【Day16】【MongoDB】【入门】

    下载,安装: http://www.mongodb.org/downloads 命令行下运行 MongoDB 服务器 为了从命令提示符下运行MongoDB服务器,你必须从MongoDB目录的bin目录 ...