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

一个字符串在原串中的出现次数就是这个字符串对应后缀自动机上的状态的\(|Right|\),要求parent树中这个状态的子树中叶子节点的个数。

因为强制在线,所以用lct维护parent树以及树上每个节点的\(|Right|\)。

注意新建\(nq\)节点时nq节点的值要设为0,因为\(nq\)节点不是叶子节点。。。

还有删整棵子树时要减去它们对它们祖先的影响。

lct模板打错,调了好长时间_(:з」∠)_

压常数?inline大法好

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std; struct node *null;
struct node {
node *ch[2], *fa;
int r, lazy;
node() {
ch[0] = ch[1] = fa = null;
r = lazy = 0;
}
bool pl() {return fa->ch[1] == this;}
bool check() {return fa == null || (fa->ch[0] != this && fa->ch[1] != this);}
void setc(node *r, bool c) {ch[c] = r; r->fa = this;}
void push() {
if (lazy != 0) {
if (ch[0] != null) ch[0]->lazy += lazy, ch[0]->r += lazy;
if (ch[1] != null) ch[1]->lazy += lazy, ch[1]->r += lazy;
lazy = 0;
}
}
}; namespace LCT {
inline void rotate(node *r) {
node *f = r->fa;
bool c = r->pl();
if (f->check()) r->fa = f->fa;
else f->fa->setc(r, f->pl());
f->setc(r->ch[!c], c);
r->setc(f, !c);
}
inline void update(node *r) {
if (!r->check())
update(r->fa);
r->push();
}
inline void splay(node *r) {
update(r);
for(; !r->check(); rotate(r))
if (!r->fa->check()) rotate(r->pl() == r->fa->pl() ? r->fa : r);
}
inline void access(node *r) {
node *y = null;
while (r != null) {
splay(r);
r->ch[1] = y;
y = r;
r = r->fa;
}
}
inline void cut_to(node *r, node *f) {
access(r); splay(r);
int tot = r->r;
node *t = r->ch[0]; t->fa = null;
t->r -= tot; t->lazy -= tot; r->ch[0] = null;
r->fa = f;
access(f); splay(f);
f->r += tot; f->lazy += tot;
}
inline void link_to(node *r, node *f) {
r->fa = f;
access(r); splay(r);
r->r = r->lazy = 1;
}
inline void link_to_nq(node *r, node *f) {
r->fa = f;
}
} struct State {
State *par, *go[26];
int val;
node *to;
State(int _val) : val(_val), par(0), to(0) {
to = new node;
memset(go, 0, sizeof(go));
}
} *root, *last; inline void extend(int w) {
State *p = last;
State *np = new State(p->val + 1);
while (p && p->go[w] == 0)
p->go[w] = np, p = p->par;
if (p == 0) {
np->par = root;
LCT::link_to(np->to, root->to);
} else {
State *q = p->go[w];
if (q->val == p->val + 1) {
np->par = q;
LCT::link_to(np->to, q->to);
} else {
State *nq = new State(p->val + 1);
memcpy(nq->go, q->go, sizeof(q->go));
nq->par = q->par;
LCT::link_to_nq(nq->to, q->par->to);
q->par = np->par = nq;
LCT::cut_to(q->to, nq->to);
LCT::link_to(np->to, nq->to);
while (p && p->go[w] == q)
p->go[w] = nq, p = p->par;
}
}
last = np;
} inline void fix(char *s, int la) {
int len = strlen(s);
for(int i = 0; i < len; ++i) {
la = (la * 131 + i) % len;
swap(s[i], s[la]);
}
} inline int find(char *s) {
State *tmp = root;
int len = strlen(s);
for(int i = 0; i < len; ++i)
if (tmp->go[s[i] - 'A']) tmp = tmp->go[s[i] - 'A'];
else return 0;
LCT::access(tmp->to);
LCT::splay(tmp->to);
return tmp->to->r;
} int q, la;
char s[3000003], w[103]; int main() {
null = new node; *null = node();
root = last = new State(0);
root->to = new node;
scanf("%d", &q);
scanf("%s", s + 1);
int len = strlen(s + 1), ans;
for(int i = 1; i <= len; ++i)
extend(s[i] - 'A'); while (q--) {
scanf("%s%s", w, s);
len = strlen(s);
fix(s, la);
if (w[0] == 'Q') {
ans = find(s);
printf("%d\n", ans);
la ^= ans;
} else {
for(int i = 0; i < len; ++i)
extend(s[i] - 'A');
}
}
return 0;
}

【BZOJ 2555】SubString的更多相关文章

  1. 【BZOJ 2555】 2555: SubString (SAM+LCT)

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

  2. 【BZOJ 1150】 1150: [CTSC2007]数据备份Backup (贪心+优先队列+双向链表)

    1150: [CTSC2007]数据备份Backup Description 你在一家 IT 公司为大型写字楼或办公楼(offices)的计算机数据做备份.然而数据备份的工作是枯燥乏味 的,因此你想设 ...

  3. Kruskal算法及其类似原理的应用——【BZOJ 3654】tree&&【BZOJ 3624】[Apio2008]免费道路

    首先让我们来介绍Krukal算法,他是一种用来求解最小生成树问题的算法,首先把边按边权排序,然后贪心得从最小开始往大里取,只要那个边的两端点暂时还没有在一个联通块里,我们就把他相连,只要这个图里存在最 ...

  4. 【BZOJ 2957】楼房重建&&Codechef COT5 Count on a Treap&&【NOIP模拟赛】Weed 线段树的分治维护

    线段树是一种作用于静态区间上的数据结构,可以高效查询连续区间和单点,类似于一种静态的分治.他最迷人的地方在于“lazy标记”,对于lazy标记一般随我们从父区间进入子区间而下传,最终给到叶子节点,但还 ...

  5. LCA 【bzoj 4281】 [ONTAK2015]Związek Harcerstwa Bajtockiego

    [bzoj 4281] [ONTAK2015]Związek Harcerstwa Bajtockiego Description 给定一棵有n个点的无根树,相邻的点之间的距离为1,一开始你位于m点. ...

  6. 【BZOJ 1191】 [Apio2010]特别行动队 (斜率优化)

    dsy1911: [Apio2010]特别行动队 [题目描述] 有n个数,分成连续的若干段,每段的分数为a*x^2+b*x+c(a,b,c是给出的常数),其中x为该段的各个数的和.求如何分才能使得各个 ...

  7. 【BZOJ 1096】 [ZJOI2007]仓库建设 (斜率优化)

    1096: [ZJOI2007]仓库建设 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3940  Solved: 1736 Description ...

  8. 【BZOJ 2132】圈地计划 && 【7.22Test】计划

    两种版本的题面 Description 最近房地产商GDOI(Group of Dumbbells Or Idiots)从NOI(Nuts Old Idiots)手中得到了一块开发土地.据了解,这块土 ...

  9. -【线性基】【BZOJ 2460】【BZOJ 2115】【HDU 3949】

    [把三道我做过的线性基题目放在一起总结一下,代码都挺简单,主要就是贪心思想和异或的高斯消元] [然后把网上的讲解归纳一下] 1.线性基: 若干数的线性基是一组数a1,a2,a3...an,其中ax的最 ...

随机推荐

  1. 在Windows Azure虚拟机上开发Windows 8 应用

    前提条件 Windows Azure开发者账号:如果您拥有微软MSDN Subscription账户,那么意味着您可免费申请Windows Azure开发者账号. 创建虚拟机 点击Windows Az ...

  2. UVa 297 Quadtrees -SilverN

    A quadtree is a representation format used to encode images. The fundamental idea behind the quadtre ...

  3. AC日记——逆波兰表达式 openjudge 3.3 1696

    1696:逆波兰表达式 总时间限制:  1000ms 内存限制:  65536kB 描述 逆波兰表达式是一种把运算符前置的算术表达式,例如普通的表达式2 + 3的逆波兰表示法为+ 2 3.逆波兰表达式 ...

  4. jquery无缝间歇向上滚动(间断滚动)

    jquery无缝间歇向上滚动 JS部份 $(function(){ var $this = $(".renav"); var scrollTimer; $this.hover(fu ...

  5. dubbo2.5.3 与spring 3.1.x 冲突

    在集成了dubbo2.5.3 的项目中初始化出现 MalformedParameterizedTypeException 检查发现这是因为dubbo2.5.3依赖的springframeworks是2 ...

  6. Validation failed for one or more entities. See 'EntityValidationErrors' property for more details.

    Validation failed for one or more entities. See 'EntityValidationErrors' property for more details. ...

  7. 【C#】【MySQL】C#获取存储过程的Output输出参数值

    创建存储过程 Create PROCEDURE MYSQL @a int, @b int, @c int output AS Set @c = @a + @b GO 通过以下方法可以获得储存过程的输出 ...

  8. Hibernate SQL Dialect 方言

    RDBMS Dialect DB2 org.hibernate.dialect.DB2Dialect DB2 AS/400 org.hibernate.dialect.DB2400Dialect DB ...

  9. Jenkins持续集成

    Jenkins持续集成 & .NET   最近受累于测试环境每次发布都很麻烦,而且我们有多个测试环境,因此专门抽时间做了Jenkins的配置和研究. 折腾了两天终于绿灯以后,先来个截图,Blu ...

  10. Oracle字符分隔函数(split)

    为了让 PL/SQL 函数返回数据的多个行,必须通过返回一个 REF CURSOR 或一个数据集合来完成.REF CURSOR 的这种情况局限于可以从查询中选择的数据,而整个集合在可以返回前,必须进行 ...