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. Java Web之会话技术

    客户端与服务器通信过程中,会产生一些数据.比如,A和B分别登陆了某宝购物网站,A买了一个Android手机,B买了一个iPhone手机,当结账时,web服务器需要分别对用户A和B的信息分别保存.根据J ...

  2. NOIP2003加分二叉树[树 区间DP]

    题目描述 设一个n个节点的二叉树tree的中序遍历为(1,2,3,…,n),其中数字1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数为di,tree及它的每个子树都 ...

  3. History 对象

    History 对象 History 对象包含用户(在浏览器窗口中)访问过的 URL. History 对象是 window 对象的一部分,可通过 window.history 属性对其进行访问. 注 ...

  4. linux系统下对网站实施负载均衡+高可用集群需要考虑的几点

    随着linux系统的成熟和广泛普及,linux运维技术越来越受到企业的关注和追捧.在一些中小企业,尤其是牵涉到电子商务和电子广告类的网站,通常会要求作负载均衡和高可用的Linux集群方案. 那么如何实 ...

  5. IE 和Firefox的js兼容性总结

    IE 和Firefox的js兼容性总结 12 August 2010 11:39 Thursday by 小屋 标签: 浏览器 方法 属性 IT 写法 一.函数和方法差异 1 . getYear()方 ...

  6. Windows 8.1 新增控件之 MenuFlyout

    开始这篇讲解前,我们先来温习一下Flyout 的内容,当触发应用中某个Button 时会有Flyout 出现提示用户该操作接下来将会发生什么.Flyout 简单来说就是一个轻量级信息提示需要用户确认或 ...

  7. DefaultFilesMiddleware中间件如何显示默认页面

    DefaultFilesMiddleware中间件如何显示默认页面 DefaultFilesMiddleware中间件的目的在于将目标目录下的默认文件作为响应内容.我们知道,如果直接请求的就是这个默认 ...

  8. gradient 线性渐变 浏览器兼容

    filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr=white, endColorstr= ...

  9. TinyFrame升级之一:框架概览

    由于之前的TinyFrame多于简单,并且只是说明原理,并无成型的框架出来,所以这次我把之前的知识进行了汇总,然后做出了这一版的TinyFrame框架. 整个框架的结构如下: TinyFrame.Da ...

  10. lecture10-模型的结合与全贝叶斯学习

    这是Hinton的第10课 这节课有两篇论文可以作为背景或者课外读物<Adaptive mixtures of local experts>和<Improving neural ne ...