【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. mongodb window安装配置

    下载mongodb安装包 1. https://www.mongodb.org/dl/win32/x86_64-2008plus-ssl?_ga=2.233271640.711265466.15193 ...

  2. Hive metastore源码阅读(二)

    最近随着项目的深入,发现hive meta有些弊端,就是你会发现它的元数据操作与操作物理集群的代码耦合在一起,非常不利于扩展.比如:在create_table的时候同时进行路径校验及创建,如下代码: ...

  3. IOS设备设计完整指南

    作为初学者,常常不知如何下手设计,IOS应用UI设计中碰到的种种基础小问题,在此都将一一得到解答.这份完整的设计指南将带你快速上手,为IOS设计出优雅的应用吧. 关于此设计指南 此设计指南描述的是如何 ...

  4. python学习:函数传参数

    #!/usr/bin/python   import sys   def isNum(s):     for i in s:         if i in '0123456789':         ...

  5. C# decimal 去掉小数点后的无效0

    c#去掉小数点后的无效0 decimal d = 0.0500m; d.ToString("0.##")就出来了 也可以这样 string.Format("{0:0.## ...

  6. 拦截窗体关闭、最大、最小事件 - Winform

    RT,不赘述,代码以下: const int WM_SYSCOMMAND = 0x112; const int SC_CLOSE = 0xF060; const int SC_MINIMIZE = 0 ...

  7. Spring MVC 原理

    一.什么是springmvc springMVC是spring框架的一个模块,springMVC和spring无需通过中间整合层进行开发. springMVC是一个基于mvc的web框架. Sprin ...

  8. 接口-以PHP为例

    <?php //使用程序模拟现实情况 //使用规范(方法/属性) interface iUSB { public function start(); public function stop() ...

  9. dubbox系列【三】——简单的dubbox提供者+消费者示例

    1.dubbox-provider示例 在eclipse中建立maven project,名为provider-parent,包含两个maven medule:provider-api 和 provi ...

  10. Office 365 共享链接直接进入编辑

    首先在Word online共享文档(不多赘述) 但这个链接打开的是预览视图,要点击右上角的"在浏览器中编辑"才能真正编辑. 但是很多情况都是没必要进入这个预览界面再编辑的.这多点 ...