2555: SubString

Time Limit: 30 Sec  Memory Limit: 512 MB

Submit: 2601  Solved: 780
[Submit][Status][Discuss]

Description

懒得写背景了,给你一个字符串init,要求你支持两个操作
    
    (1):在当前字符串的后面插入一个字符串
    
    (2):询问字符串s在当前字符串中出现了几次?(作为连续子串)
    
    你必须在线支持这些操作。
    
 

Input

第一行一个数Q表示操作个数
    
    第二行一个字符串表示初始字符串init
    
    接下来Q行,每行2个字符串Type,Str 
    
    Type是ADD的话表示在后面插入字符串。
    
    Type是QUERY的话表示询问某字符串在当前字符串中出现了几次。
    
    为了体现在线操作,你需要维护一个变量mask,初始值为0
   
    
    读入串Str之后,使用这个过程将之解码成真正询问的串TrueStr。
    询问的时候,对TrueStr询问后输出一行答案Result
    然后mask = mask xor Result  
    插入的时候,将TrueStr插到当前字符串后面即可。

 

HINT:ADD和QUERY操作的字符串都需要解压

Output

 

Sample Input

2

A

QUERY B

ADD BBABBBBAAB

 

Sample Output

0
 

HINT

 

40 % 的数据字符串最终长度 <= 20000,询问次数<= 1000,询问总长度<= 10000

100 % 的数据字符串最终长度 <= 600000,询问次数<= 10000,询问总长度<= 3000000

 

新加数据一组--2015.05.20

 

 

Source

 

  • 答案显然是目标串状态的right集合的大小,因为要在线我们可以用LCT来维护parent树。也就是说每次将当前点到根节点路径上的right +1
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
//---------------------LCT----------------------
const int M=3e6+;
int n,m,fa[M],st[M],c[M][];
bool rev[M];
int tag[M];
int val[M];
bool isroot(int x){
return c[fa[x]][]!=x&&c[fa[x]][]!=x;
}
/*void update(int x){
val[x]=val[c[x][0]]+val[c[x][1]]+1;
}*/
void opera(int x,int v){
if(x) tag[x]+=v,val[x]+=v;
}
void rotate(int x){
int y=fa[x],z=fa[y],l,r;
l=(c[y][]==x);r=l^;
if(!isroot(y)) c[z][c[z][]==y]=x;
fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
c[y][l]=c[x][r];c[x][r]=y;
//update(y);update(x);
}
#define l c[x][0]
#define r c[x][1]
void pushdown(int x){
/*if(rev[x]){
rev[x]^=1;rev[l]^=1;rev[r]^=1;
swap(l,r);
}*/
if(tag[x]){
opera(l,tag[x]);
opera(r,tag[x]);
tag[x]=;
}
}
void splay(int x){
int top=;st[++top]=x;
for(int i=x;!isroot(i);i=fa[i]) st[++top]=fa[i];
for(int i=top;i;i--) pushdown(st[i]);
while(!isroot(x)){
int y=fa[x],z=fa[y];
if(!isroot(y)){
if((c[y][]==x)^(c[z][]==y)) rotate(x);
else rotate(y);
}
rotate(x);
}
}
void access(int x){
for(int t=;x;x=fa[x]) splay(x),c[x][]=t,t=x;
}
/*void evert(int x){
access(x);splay(x);rev[x]^=1;
}*/
void link(int x,int y){
fa[x]=y;access(y);splay(y);
//evert(x);fa[x]=y;splay(x);
opera(y,val[x]);
}
/*void cut(int x,int y){
evert(x);
access(y);splay(y);
opera(y,-val[y]);
c[y][0]=fa[c[y][0]]=0;//!!!
}*/
void cut(int x){
access(x);splay(x);opera(l,-val[x]);
c[x][]=fa[c[x][]]=;
}
int find(int x){
access(x);splay(x);
for(;l;x=l);
return x;
}
#undef l
#undef r
//---------------------SAM----------------------
const int N=1.2e6+;
int p,q,np,nq;
int last,cnt,len,mask;
int l[N],par[N],tr[N][];
int siz[N];char s[N];
inline void extend(int c){
p=last;np=last=++cnt;val[np]=;l[np]=l[p]+;
for(;p&&!tr[p][c];tr[p][c]=np,p=par[p]);
if(!p) par[np]=,link(np,);
else{
q=tr[p][c];
if(l[p]+==l[q]) par[np]=q,link(np,q);
else{
nq=++cnt;l[nq]=l[p]+;cut(q);
memcpy(tr[nq],tr[q],sizeof tr[q]);
par[nq]=par[q];
link(nq,par[q]);
// siz[nq]=siz[q];
par[np]=par[q]=nq;
link(np,nq);link(q,nq);
for(;tr[p][c]==q;tr[p][c]=nq,p=par[p]);
}
}
// for(;np;np=par[np]) siz[np]++;
}
inline void build(){
for(int i=;i<len;i++) extend(s[i]-'A');
}
inline int query(){
int p=;
for(int i=,c;i<len;i++){
c=s[i]-'A';
if(!tr[p][c]) return ;
p=tr[p][c];
}
splay(p);
mask^=val[p];
return val[p];
}
inline void decode(int mask){
len=strlen(s);
for(int i=;i<len;i++){
mask=(mask*+i)%len;
swap(s[mask],s[i]);
}
}
int main(){
last=++cnt;
scanf("%d",&m);scanf("%s",s);len=strlen(s);
build();
for(char op[];m--;){
scanf("%s%s",op,s);decode(mask);
if(op[]=='A')
build();
else
printf("%d\n",query());
}
return ;
}

2555: SubString[LCT+SAM]的更多相关文章

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

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

  2. bzoj 2555 SubString(SAM+LCT)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2555 [题意] 给定一个字符串,可以随时插入字符串,提供查询s在其中作为连续子串的出现 ...

  3. P5212 SubString LCT+SAM

    $ \color{#0066ff}{ 题目描述 }$ 给定一个字符串init,要求支持两个操作 在当前字符串的后面插入一个字符串 询问字符串ss在当前字符串中出现了几次?(作为连续子串) 强制在线. ...

  4. bzoj 2555: SubString 后缀自动机+LCT

    2555: SubString Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 688  Solved: 235[Submit][Status][Dis ...

  5. 字符串(LCT,后缀自动机):BZOJ 2555 SubString

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

  6. BZOJ 2555 SubString(LCT+后缀树)

    喜闻乐见的LCT+SAM 此题要求动态插入,直接上后缀树.然后询问其实就是求一个节点的子树后缀结束节点的个数. 因为建立后缀树需要插入和删除,就直接上LCT.每次加入一个点,把它到根的路径加一 (现在 ...

  7. 2555: SubString

    2555: SubString 链接 题意: 动态在末尾加入一个字符串,询问一个字符串出现了多少次. 分析: 如果没有动态加入,那么建出SAM后,求出parent树上,每个点|Right|,然后走一遍 ...

  8. [BZOJ2555]SubString LCT+后缀自动机

    2555: SubString Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 3253  Solved: 975[Submit][Status][Di ...

  9. 【刷题】BZOJ 2555 SubString

    Description 懒得写背景了,给你一个字符串init,要求你支持两个操作 (1):在当前字符串的后面插入一个字符串 (2):询问字符串s在当前字符串中出现了几次?(作为连续子串) 你必须在线支 ...

随机推荐

  1. idea过期激活

    1.进到文件夹中:C:\Windows\System32\drivers\etc ,找到hosts文件,用记事本编辑 2.将“  0.0.0.0 account.jetbrains.com ”添加到h ...

  2. linux内置软件安装命令

    yum -y install epel-release

  3. Lucene基础学习笔记

    在学校和老师一起做项目,在老师的推荐下深入学习了一些SqlServer的知识,看一些书下来哎也没记住多少,不过带来了新疑问. 不使用模糊查询,我应该用什么呢?如何能不影响数据库性能,还能做模糊查询呢? ...

  4. 带你玩转Eclipse项目转成AndroidStudio项目

    随着Android对Eclipse开发工具的淘汰,越来越多的公司使用AndroidStudio进行相应的Android开发工作.如此,原来用Eclipse开发的项目,怎么导入到AndroidStudi ...

  5. 通过tarball形式安装HBASE Cluster(CDH5.0.2)——如何配置分布式集群中的zookeeper

    集群安装总览参见这里 Zookeeper的配置 1,/etc/profile中加入zk的路径设置,见上面背景说明. 2,进入~/zk/conf目录,复制zoo_sample.cfg为zoo.cfg v ...

  6. react解析html标签组成的字符串

    转载自:https://blog.csdn.net/tongshuo_11/article/details/61195232 var content = '<strong>content& ...

  7. vue路由跳转报错解决

    vue路由跳转: setTimeout(function () { console.log(this); this.$router.push("/login"); },800) 语 ...

  8. 实现一个div,左边固定div宽度200px,右边div自适应

    实现一个div,左边固定div宽度200px,右边div自适应<div class= "container"> <div class="left&quo ...

  9. python打造线程池

    # coding=utf-8 import threading import Queue import time import traceback class ThreadPoolExecutor(o ...

  10. orcle时间

    Oracle计算时间差函数 两个Date类型字段:START_DATE,END_DATE,计算这两个日期的时间差 (分别以天,小时,分钟,秒,毫秒): 天: ROUND(TO_NUMBER(END_D ...