【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入门学习笔记(2)——基于Java的配置
目录 基于Java的配置 @Configuration & @Bean Annotations Example 注入Bean依赖 @Import注解 Lifecycle Callbacks(声 ...
- kubernetes dashboard 安装时出现9090: getsockopt: connection refused错误
转载于:https://blog.csdn.net/lucy06/article/details/79082302 安装kubernetes dashboard时,出现错误: Error: 'dia ...
- NO.4:自学python之路------内置方法、装饰器、迭代器
引言 是时候开始新的Python学习了,最近要考英语,可能不会周更,但是尽量吧. 正文 内置方法 Python提供给了使用者很多内置方法,可以便于编程使用.这里就来挑选其中大部分的内置方法进行解释其用 ...
- Ubuntu16.04安装vmware workstation14
1.获得vmware安装包:https://www.vmware.com/products/workstation-pro/workstation-pro-evaluation.html?ClickI ...
- 深入理解Java类加载器(ClassLoader) (转)
转自: http://blog.csdn.net/javazejian/article/details/73413292 关联文章: 深入理解Java类型信息(Class对象)与反射机制 深入理解Ja ...
- 第十一次PSP
- 浅学CSS
CSS 规则由两个主要的部分构成:选择器,以及一条或多条声明: 选择器通常是您需要改变样式的 HTML 元素. 每条声明由一个属性和一个值组成. 属性(property)是您希望设置的样式属性(sty ...
- 一个C++bug引入的许多知识
一.前言 假设我们有一个Car类,用了表示一个车,它有id,名字,牌照等许多东西,还有一个表示车的部件CarPart. 但出于某方面的考虑,我们不打算在产生car这个对象的时候,就生产出这个车,你可以 ...
- jsp 页面和 jsp标记
一个jsp页面可由5种元素组成 html标记 变量和方法的声明 java程序片 java表达式 <%!变量和方法的声明%> 被声明的方法和变量在整个jsp页面都可以访问,为全局变量 当多个 ...
- Beta阶段——第一篇 Scrum 冲刺博客
i. 提供当天站立式会议照片一张: ii. 每个人的工作 (有work item 的ID) (1) 昨天已完成的工作: 数据存储方式改本地存储为数据库存储. (2) 今天计划完成的工作: 账单和剩余舍 ...