喜闻乐见的LCT+SAM

此题要求动态插入,直接上后缀树。然后询问其实就是求一个节点的子树后缀结束节点的个数。

因为建立后缀树需要插入和删除,就直接上LCT。每次加入一个点,把它到根的路径加一

(现在我才知道access之后那个splay就是这个点到根的路径,LCT学得不好)

思路不需要说太多,就是码量大。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=3001000;
int T,ans;
char s[N];
int read(){
int sum=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){sum=sum*10+ch-'0';ch=getchar();}
return sum*f;
}
int get(int ans){
cin>>s;
int len=strlen(s);
for (int j=0;j<len;j++) {
ans=(ans*131+j)%len;
char c=s[j];
s[j]=s[ans];
s[ans]=c;
}
return len;
}
struct lct{
int fa[N],ch[N][2],w[N],lazy[N],stack[N];
void add(int x,int y){
w[x]+=y;lazy[x]+=y;
}
void pushdown(int x){
if(lazy[x]){
add(ch[x][0],lazy[x]);add(ch[x][1],lazy[x]);
lazy[x]=0;
}
}
bool isroot(int x){
return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;
}
bool son(int x){
return ch[fa[x]][1]==x;
}
void rotate(int x){
int y=fa[x],z=fa[y],a=son(x),b=son(y),c=ch[x][!a];
if(!isroot(y))ch[z][b]=x;fa[x]=z;
if(c)fa[c]=y;ch[y][a]=c;
ch[x][!a]=y;fa[y]=x;
}
void splay(int x){
int top=1,a=x;stack[top]=a;
while(a)stack[++top]=a=fa[a];
while(top)pushdown(stack[top--]);
while(!isroot(x)){
int y=fa[x],z=fa[y];
if(isroot(y))rotate(x);
else{
if(son(x)==son(y))rotate(y);
else rotate(x);
rotate(x);
}
}
}
void access(int x){
for(int j=0;x;j=x,x=fa[x])
splay(x),ch[x][1]=j;
}
void link(int x,int f){
fa[x]=f;access(f);splay(f);add(f,w[x]);
}
void cut(int x){
access(x);splay(x);add(ch[x][0],-w[x]);
fa[ch[x][0]]=0;ch[x][0]=0;
}
}t;
struct SAM{
int tot,u,ln[N],size[N],trans[N][27],fa[N];
void ins(int c){
int x=++tot;ln[x]=ln[u]+1;size[x]=1;
t.w[x]=1;
for(;u&&trans[u][c]==0;u=fa[u])trans[u][c]=x;
if(u==0)fa[x]=1,t.link(x,1);
else{
int v=trans[u][c];
if(ln[v]==ln[u]+1)fa[x]=v,t.link(x,v);
else{
int w=++tot;
ln[w]=ln[u]+1;fa[w]=fa[v];
t.link(w,fa[w]);
memcpy(trans[w],trans[v],sizeof(trans[w]));
fa[x]=fa[v]=w;
t.cut(v);t.link(v,w);t.link(x,w);
for(;u&&trans[u][c]==v;u=fa[u])trans[u][c]=w;
}
}
u=x;
}
void add(){
int len=get(ans);
for(int i=0;i<len;i++)ins(s[i]-'A'+1);
}
int check(){
int len=get(ans);
int now=1;
for(int i=0;i<len;i++){
if(trans[now][s[i]-'A'+1]==0)return 0;
now=trans[now][s[i]-'A'+1];
}
t.splay(now);
return t.w[now];
}
}sam;
int main(){
T=read();
sam.tot=sam.u=1;
cin>>s;
int len=strlen(s);
for(int i=0;i<len;i++)sam.ins(s[i]-'A'+1);
while(T--){
cin>>s;
if(s[0]=='Q'){
int tmp=sam.check();
printf("%d\n",tmp);
ans^=tmp;
}
else sam.add();
}
return 0;
}

BZOJ 2555 SubString(LCT+后缀树)的更多相关文章

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

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

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

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

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

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

  4. ●BZOJ 2555 SubString

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

  5. 2555: SubString[LCT+SAM]

    2555: SubString Time Limit: 30 Sec  Memory Limit: 512 MB Submit: 2601  Solved: 780 [Submit][Status][ ...

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

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

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

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

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

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

  9. bzoj 2555 SubString(SAM+LCT)

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

随机推荐

  1. Java用freemarker导出Word 文档

    1.用Microsoft Office Word打开word原件: 2.把需要动态修改的内容替换成***,如果有图片,尽量选择较小的图片几十K左右,并调整好位置: 3.另存为,选择保存类型Word 2 ...

  2. vuex存储和本地存储的区别

    1.实质的区别 vuex存的是状态,存储在内存,localstorage是浏览器提供的接口,让你存的是文件,以文件的形式存储在本地 2.应用场景 vuex用于组件之间的传值,localstorage则 ...

  3. Xcode10适配——Error:Multiple commands produce

    今天苹果正式推送了iOS12,今天上午就更新了最新的iOS,及Xcode10.这次更新还行,不需要我们对以前的项目紧急修复,大动手术. 用Xcode10跑之前的项目,也就报了一种类型的错误:Multi ...

  4. .Net调用Java编写的WebServices返回值为Null的解决方法(SoapUI工具测试有返回值)

    最近在项目中与别的公司对接业务,对方是Java语言,需要调用对方的WebServices,结果常规的添加web引用的方法可以传过去值,但是返回值为null 查了很多资料,没有解决方法 思考应该是.Ne ...

  5. java实现组合数_n!_杨辉三角_组合数递推公式_回文数_汉诺塔问题

    一,使用计算机计算组合数 1,设计思想 (1)使用组合数公式利用n!来计算Cn^k=n!/k!(n-k)!用递推计算阶乘 (2)使用递推的方法用杨辉三角计算Cn+1^k=Cn^k-1+Cn^k 通过数 ...

  6. Git中的工作区(Working Directory)、暂存区(stage)和历史记录区(history)

    今天和git搏斗了一下午,发现了修改的文件一直commit不了.网上查了一下才发现原来git的模型里还有工作区和暂存区的说法. 工作区:在git管理下的正常目录都算是工作区.我们平时的编辑工作都是在工 ...

  7. WampServer更改或重置数据库密码

    WampServer安装后密码是空的, 修改一般有两种方式: 一是通过phpMyAdmin直接修改: 二是使用WAMP的MySql控制台修改. 第一种: ①在phpMyAdmin界面中点击[用户],将 ...

  8. 【Codeforces Round #499 (Div. 2) E】Border

    [链接] 我是链接,点我呀:) [题意] 给你n个数字,每个数字可以无限用,每种方案可以组成一个和,问你%k的结果有多少种不同的结果. [题解] 相当于给你一个方程 \(x_1*a_1+x_2*a_2 ...

  9. ubuntu 14.04服务器上使用nginx搭建wordpress博客详解

    过程详解 1.更新apt-get sudo apt-get update 2.安装nginx sudo apt-get install nginx 3.启动nginx sudo service ngi ...

  10. 数据库范式1NF 2NF 3NF BCNF(实例)通俗易懂的讲解

    [转] 数据库范式1NF 2NF 3NF BCNF(实例)通俗易懂的讲解     本文对大多数初学数据库原理的同学绝对是个大福利,哈哈,完完整整的看完此篇博文一定能够清晰地理解数据库的四大范式.    ...