【BZOJ2555】SubString(后缀自动机,Link-Cut Tree)

题面

BZOJ

题解

这题看起来不难

每次要求的就是\(right/endpos\)集合的大小

所以搞一个\(LCT\)维护一下\(SAM\)的\(Parent\)树就好了

但是代码一点都不好写(我还是对着黄学长的调的。。。)

于是乎我也学着魔改了一下\(LCT\)

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define MAX 600006
char ch[MAX];
inline int read()
{
int x=0,t=1;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
int mask,ans;
struct LCT
{
#define lson (t[x].ch[0])
#define rson (t[x].ch[1])
struct Node
{
int ch[2],ff;
int rev,v,ly;
}t[MAX<<1];
int S[MAX<<1],top;
bool isroot(int x){return t[t[x].ff].ch[0]!=x&&t[t[x].ff].ch[1]!=x;}
void rotate(int x)
{
int y=t[x].ff,z=t[y].ff;
int k=t[y].ch[1]==x;
if(!isroot(y))t[z].ch[t[z].ch[1]==y]=x;t[x].ff=z;
t[y].ch[k]=t[x].ch[k^1];t[t[x].ch[k^1]].ff=y;
t[x].ch[k^1]=y;t[y].ff=x;
}
void putrev(int x){swap(lson,rson);t[x].rev^=1;}
void putly(int x,int v){t[x].v+=v;t[x].ly+=v;}
void pushdown(int x)
{
if(t[x].rev)
{
if(lson)putrev(lson);
if(rson)putrev(rson);
t[x].rev^=1;
}
if(t[x].ly!=0)
{
if(lson)putly(lson,t[x].ly);
if(rson)putly(rson,t[x].ly);
t[x].ly=0;
}
}
void Splay(int x)
{
S[top=1]=x;
for(int i=x;!isroot(i);i=t[i].ff)S[++top]=t[i].ff;
while(top)pushdown(S[top--]);
while(!isroot(x))
{
int y=t[x].ff,z=t[y].ff;
if(!isroot(y))
(t[z].ch[1]==y)^(t[y].ch[1]==x)?rotate(x):rotate(y);
rotate(x);
}
}
void access(int x){for(int y=0;x;y=x,x=t[x].ff)Splay(x),rson=y;}
void makeroot(int x){access(x);Splay(x);putrev(x);}
void split(int x,int y){makeroot(x);access(y);Splay(y);}
void cut(int x){access(x);Splay(x);putly(lson,-t[x].v);t[lson].ff=0;lson=0;}
void link(int x,int f){t[x].ff=f;access(f);Splay(f);putly(f,t[x].v);}
int findroot(int x){access(x);Splay(x);while(lson)x=lson;return x;}
}LCT;
struct SAM
{
struct Node
{
int son[26];
int ff,len;
}t[MAX<<1];
int last,tot;
void init(){last=tot=1;}
void extend(int c)
{
int p=last,np=++tot;last=np;LCT.t[np].v=1;
while(p&&!t[p].son[c])t[p].son[c]=np,p=t[p].ff;
if(!p)t[np].ff=1,LCT.link(np,1);
else
{
int q=t[p].son[c];
if(t[q].len==t[p].len+1)t[np].ff=q,LCT.link(np,q);
else
{
int nq=++tot;
t[nq]=t[q];
t[nq].len=t[p].len+1;
LCT.link(nq,t[q].ff);
t[q].ff=t[np].ff=nq;
LCT.cut(q);LCT.link(q,nq);LCT.link(np,nq);
while(p&&t[p].son[c]==q)t[p].son[c]=nq,p=t[p].ff;
}
}
}
}SAM;
void Decode(char *ch,int mask)
{
int l=strlen(ch);
for(int i=0;i<l;++i)
{
mask=(mask*131+i)%l;
swap(ch[i],ch[mask]);
}
}
int main()
{
int Q=read();
SAM.init();
scanf("%s",ch+1);
for(int i=1,l=strlen(ch+1);i<=l;++i)SAM.extend(ch[i]-'A');
while(Q--)
{
scanf("%s",ch);
if(ch[0]=='A')
{
scanf("%s",ch+1);
Decode(ch+1,mask);
for(int i=1,l=strlen(ch+1);i<=l;++i)SAM.extend(ch[i]-'A');
}
else
{
scanf("%s",ch+1);
Decode(ch+1,mask);
int now=1;
for(int i=1,l=strlen(ch+1);i<=l;++i)
now=SAM.t[now].son[ch[i]-'A'];
if(!now)printf("%d\n",ans=0);
else
{
LCT.Splay(now);
printf("%d\n",ans=LCT.t[now].v);
}
mask^=ans;
}
}
return 0;
}

【BZOJ2555】SubString(后缀自动机,Link-Cut Tree)的更多相关文章

  1. BZOJ2555 SubString【SAM + Link Cut Tree】

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

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

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

  3. link cut tree 入门

    鉴于最近写bzoj还有51nod都出现写不动的现象,决定学习一波厉害的算法/数据结构. link cut tree:研究popoqqq那个神ppt. bzoj1036:维护access操作就可以了. ...

  4. Codeforces Round #339 (Div. 2) A. Link/Cut Tree 水题

    A. Link/Cut Tree 题目连接: http://www.codeforces.com/contest/614/problem/A Description Programmer Rostis ...

  5. Link/cut Tree

    Link/cut Tree 一棵link/cut tree是一种用以表示一个森林,一个有根树集合的数据结构.它提供以下操作: 向森林中加入一棵只有一个点的树. 将一个点及其子树从其所在的树上断开. 将 ...

  6. 洛谷P3690 Link Cut Tree (模板)

    Link Cut Tree 刚开始写了个指针版..调了一天然后放弃了.. 最后还是学了黄学长的板子!! #include <bits/stdc++.h> #define INF 0x3f3 ...

  7. LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)

    为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...

  8. bzoj2049 [Sdoi2008]Cave 洞穴勘测 link cut tree入门

    link cut tree入门题 首先说明本人只会写自底向上的数组版(都说了不写指针.不写自顶向下QAQ……) 突然发现link cut tree不难写... 说一下各个函数作用: bool isro ...

  9. P3690 【模板】Link Cut Tree (动态树)

    P3690 [模板]Link Cut Tree (动态树) 认父不认子的lct 注意:不 要 把 $fa[x]$和$nrt(x)$ 混 在 一 起 ! #include<cstdio> v ...

随机推荐

  1. vue环境搭建与创建第一个vuejs文件

    我们在前端学习中,学会了HTML.CSS.JS之后一般会选择学习一些框架,比如Jquery.AngularJs等.这个系列的博文是针对于学习Vue.js的同学展开的. 1.如何简单地使用Vue.js ...

  2. php读取文件内容的三种方法

    <?php //**************第一种读取方式***************************** 代码如下: header("content-type:text/h ...

  3. /dev/null 2>&1 详解

     今天一个朋友突然在自己的维护的Linux中, /var/spool/cron/root 中看到了以下的内容: 30 19 * * * /usr/bin/**dcon.sh > /dev/nul ...

  4. php 高并发下 秒杀处理思路

    1.用额外的单进程处理一个队列,下单请求放到队列里,一个个处理,就不会有并发的问题了,但是要额外的后台进程以及延迟问题,不予考虑. 2.数据库乐观锁,大致的意思是先查询库存,然后立马将库存+1,然后订 ...

  5. 解决react-router4在browserhistory路由下的nginx的白屏或者404问题

    使用react-router,官方推荐用browserhistory,美观简洁.但是nginx服务器端的配置也让人头疼. 首先看官方举例的方法: server { location / { try_f ...

  6. 获取目录-Winform

    // 获取程序的基目录. System.AppDomain.CurrentDomain.BaseDirectory // 获取模块的完整路径. System.Diagnostics.Process.G ...

  7. ucore文件系统详解

    最近一直在mooc上学习清华大学的操作系统课程,也算是复习下基本概念和原理,为接下来的找工作做准备. 每次深入底层源码都让我深感操作系统实现的琐碎,即使像ucore这样简单的kernel也让我烦躁不已 ...

  8. CentOS7关闭/开启防火墙出现 Unit iptables.service failed to load

    在vm中安装好tomcat,而且在liunx中使用nc命令可以返回成功,但是更换到window中访问不到tomcat的情况,是由于linux防火墙的问题造成的,传统的解决方式有2中 第一种解决方案: ...

  9. Yii的HTML助手

    Html 帮助类 基础 表单 样式表和脚本 超链接 图片 列表 任何一个 web 应用程序会生成很多 HTMl 超文本标记.如果超文本标记是静态的, 那么将 PHP 和 HTML 混合在一个文件里 这 ...

  10. LeetCode第四天

    leetcode 第四天 2018年1月4日 15.(628)Maximum Product of Three Numbers JAVA class Solution { public int max ...