【bzoj2555】 SubString
http://www.lydsy.com/JudgeOnline/problem.php?id=2555 (题目链接)
题意
给出一个初始串,维护两个操作。在原串后面加入一个字符串;询问某个字符串在原串中出现的次数。强制在线。
Solution
对于加入操作,我们动态构造后缀自动机,每次就将添加的节点${parent}$树上到根节点的路径上的节点的${right}$集合大小全部加${1}$。树上路径区间加法,有因为这是个动态树,所以我们用${LCT}$维护${parent}$树就可以了。
细节
坑死了,解码过程中${mask}$是不变的,只有在询问之后才会异或上答案发生改变。幸好看了${PoPoQQQ}$大爷的博客→_→
代码
// bzoj2555
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<ctime>
#define RG register
#define LL long long
#define inf (1ll<<30)
#define MOD 1000000007
#define Pi acos(-1.0)
#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
using namespace std; const int maxn=600010,maxm=3000010;
char s[maxm];
int Q,mask,r[maxn<<1]; namespace LCT {
int tr[maxn<<1][2],fa[maxn<<1],tag[maxn<<1]; void pushdown(int x) {
if (tr[fa[x]][0]==x || tr[fa[x]][1]==x) pushdown(fa[x]);
if (tag[x]) {
r[tr[x][0]]+=tag[x];tag[tr[x][0]]+=tag[x];
r[tr[x][1]]+=tag[x];tag[tr[x][1]]+=tag[x];
tag[x]=0;
}
}
void rotate(int x) {
int y=fa[x],z=fa[y],l,r;
l=tr[y][1]==x;r=l^1;
if (tr[z][0]==y || tr[z][1]==y) tr[z][tr[z][1]==y]=x;
fa[x]=z;fa[y]=x;fa[tr[x][r]]=y;
tr[y][l]=tr[x][r];tr[x][r]=y;
}
void splay(int x) {
pushdown(x);
while (tr[fa[x]][0]==x || tr[fa[x]][1]==x) {
int y=fa[x],z=fa[y];
if (tr[z][0]==y || tr[z][1]==y) {
if (tr[z][0]==y ^ tr[y][0]==x) rotate(x);
else rotate(y);
}
rotate(x);
}
}
void access(int x) {
for (int y=0;x;y=x,x=fa[x])
splay(x),tr[x][1]=y;
}
void add(int x,int val) {
r[x]+=val;tag[x]+=val;
}
void link(int x,int y) {
access(y);splay(y);add(y,r[x]);
fa[x]=y;
}
void cut(int x) {
access(x);splay(x);add(tr[x][0],-r[x]);
tr[x][0]=fa[tr[x][0]]=0;
}
int query(int x) {
splay(x);return r[x];
}
}
using namespace LCT; namespace SAM {
int Dargen,last,sz;
int len[maxn<<1],ch[maxn<<1][26],par[maxn<<1];
void Init() {Dargen=last=sz=1;}
void Extend(int c) {
int np=++sz,p=last;last=np;
len[np]=len[p]+1;r[np]=1;
for (;p && !ch[p][c];p=par[p]) ch[p][c]=np;
if (!p) par[np]=Dargen,link(np,Dargen);
else {
int q=ch[p][c];
if (len[p]+1==len[q]) par[np]=q,link(np,q);
else {
int nq=++sz;len[nq]=len[p]+1;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
par[nq]=par[q],link(nq,par[q]);
par[np]=par[q]=nq;
cut(q),link(np,nq),link(q,nq);
for (;p && ch[p][c]==q;p=par[p]) ch[p][c]=nq;
}
}
}
int match(char *r) {
int p=Dargen,l=strlen(r);
for (int i=0;i<l;i++) {
if (!ch[p][r[i]-'A']) return 0;
p=ch[p][r[i]-'A'];
}
return query(p);
}
}
using namespace SAM; void decode(char *r,int t) {
int len=strlen(r);
for (int j=0;j<len;j++) {
t=(t*131+j)%len;
swap(r[j],r[t]);
}
}
int main() {
scanf("%d",&Q);
scanf("%s",s+1);
Init();
int n=strlen(s+1);
for (int i=1;i<=n;i++) Extend(s[i]-'A');
char ch[10];mask=0;
while (Q--) {
scanf("%s%s",ch,s);
decode(s,mask);
n=strlen(s);
if (ch[0]=='A') for (int i=0;i<n;i++) Extend(s[i]-'A');
if (ch[0]=='Q') {
int ans=match(s);
mask^=ans;
printf("%d\n",ans);
}
}
return 0;
}
【bzoj2555】 SubString的更多相关文章
- 【BZOJ2555】SubString(后缀自动机,Link-Cut Tree)
[BZOJ2555]SubString(后缀自动机,Link-Cut Tree) 题面 BZOJ 题解 这题看起来不难 每次要求的就是\(right/endpos\)集合的大小 所以搞一个\(LCT\ ...
- 【BZOJ2555】SubString 后缀自动机+LCT
[BZOJ2555]SubString Description 懒得写背景了,给你一个字符串init,要求你支持两个操作 (1):在当前字符串的后面插入一个字符串 (2 ...
- 【BZOJ-2555】SubString 后缀自动机 + LinkCutTree
2555: SubString Time Limit: 30 Sec Memory Limit: 512 MBSubmit: 1936 Solved: 551[Submit][Status][Di ...
- 【BZOJ2555】SubString
算是学会sam了吧…… 原题: 懒得写背景了,给你一个字符串init,要求你支持两个操作 (1):在当前字符串的后面插入一个字符串 (2):询问字符串s在当前字符串中出现了 ...
- 【BZOJ2555】SubString(后缀自动机,LCT)
题意:给你一个字符串init,要求你支持两个操作 (1):在当前字符串的后面插入一个字符串 (2):询问字符串s在当前字符串中出现了几次?(作为连续子串) 你必须在线支持这些操作. 长度 <= ...
- 【leetcode】Substring with Concatenation of All Words
Substring with Concatenation of All Words You are given a string, S, and a list of words, L, that ar ...
- 【leetcode】Substring with Concatenation of All Words (hard) ★
You are given a string, S, and a list of words, L, that are all of the same length. Find all startin ...
- 【LeetCode】哈希表 hash_table(共88题)
[1]Two Sum (2018年11月9日,k-sum专题,算法群衍生题) 给了一个数组 nums, 和一个 target 数字,要求返回一个下标的 pair, 使得这两个元素相加等于 target ...
- 【LeetCode】字符串 string(共112题)
[3]Longest Substring Without Repeating Characters (2019年1月22日,复习) [5]Longest Palindromic Substring ( ...
随机推荐
- Spring学习(5):DI的配置
一. 一些概念 应用程序中说的依赖一般指类之间的关系. 泛化:表示类与类之间的继承关系.接口与接口之间的继承关系: 实现:表示类对接口的实现: 依赖:当类与类之间有使用关系时就属于依赖关系,不同于关 ...
- AtCoder | ARC103 | 瞎讲报告
目录 ARC 103 A.//// B.Robot Arms C.Tr/ee D.Distance Sums ARC 103 窝是传送门QwQ A.//// 题意 : 给你\(n\)(\(n\)为偶数 ...
- Django_rest_framework_版本(待验证)
简介 API版本控制可以用来在不同的客户端使用不同的行为.REST框架提供了大量不同的版本设计. 版本控制是由传入的客户端请求决定的,并且可能基于请求URL,或者基于请求头. 有许多有效的方法达到版本 ...
- Task 6.1 校友聊之NABCD模型分析
我们团队开发的一款软件是“校友聊”--一个在局域网内免流量进行文字.语音.视频聊天的软件.下面将对此进行NABCD的模型分析. N(Need需求):现如今,随着网络的迅速普及,手机和电脑已经成为每个大 ...
- DPDK QoS_meter 源码阅读
main.c /* SPDX-License-Identifier: BSD-3-Clause * Copyright(c) 2010-2016 Intel Corporation */ #inclu ...
- Unity3D游戏开发——物品存储:List与Dictionary
本篇简介 本文介绍如何将碰撞处理后的物体存储在管理器中,分别用到两种不同的数据结构--List和Dictionary.我们将继续在上一篇博客的编程基础上进行完善. List和Dictionary的区别 ...
- HTTPS链式编程——AFNetworking 3.0
1. HTTPS 证书认证(导入相关证书) #pragma mark - https认证 - (AFSecurityPolicy*)customSecurityPolicy { // 先导入证书 NS ...
- JabRef学习笔记(一)
JabRef简介 JabRef is an open source bibliography reference manager. The native file format used by Jab ...
- input、textArea实时显示剩余可输入的字数
<h2>实时显示剩余可输入的字数(字母,数字,中文都算一个字)</h2> <h>昵称:</h> <div> <input type=& ...
- Java多线程(五) —— 线程并发库之锁机制
参考文献: http://www.blogjava.net/xylz/archive/2010/07/08/325587.html 一.Lock与ReentrantLock 前面的章节主要谈谈原子操作 ...