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. .OFF 格式文件

    转载:http://blog.sina.com.cn/s/blog_643634b80102v166.html 物体文件格式(.off)文件通过描述物体表面的多边形来表示一个模型的几何结构,这里的多边 ...

  2. 使用nginx反向代理解决前端跨域问题

    1. 首先去Nginx官网下载一个最新版本的Nginx,下载地址:http://nginx.org/en/download.html.我这里下载的版本是:nginx/Windows-1.12.0.下载 ...

  3. shell特殊符号cut命令 sort_wc_uniq命令 tee_tr_split命令 shell特殊符号

    shell特殊符号cut命令 特殊符号 *  通配符,任意个任意字符 ? 任意一个字符 # 注释字符 \  脱义字符 c=\$a\$b echo  $c | 管道符 cat  1.txt |less ...

  4. categorys

    //spark-shell --driver-class-path /home/hadoop/test/mysqljdbc.jarimport java.sql.DriverManager// --q ...

  5. 内存管理 初始化(八) 至kswapd_init

    至此,内存初始化部分已看完,遗留问题: 1.对于unicore或者mips的页表建立都很清楚,但是对于ARM我不清楚: 初始化部分涉及的页表映射建立,我都以unicore架构为准,ARM的页表映射从原 ...

  6. z-index 层级关系

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  7. eclipse中设置文件的编码格式为utf-8

    1.可以在 eclipse 中配置 workspace 项下 text file encoding 属性的值来决定此工作区间下所有的 eclipse 项目的文档的编码属性. Window-->P ...

  8. mongodb 按照时间聚类 java

    当存储到mongodb中的是string类型的时间,小tips: 1. 那么在对此域按照时间聚类(每周,每月)时就不能直接使用mongodb的time关键字了,因为mongodb有自己的时间类型,且目 ...

  9. Spring容器AOP的理解

    一句话理解:根据被代理对象信息通过Proxy动态生成我们具体的代理类. 实现就动态代理.那动态代理是什么呢? 动态代理其实并不是什么新鲜的东西,学过设计模式的人都应该知道代理模式,代理模式就是一种静态 ...

  10. WAF Bypass数据库特性(MSsql探索篇)

    0x01 背景 探索玩了Mysql特性,继续来探索一下MSsql特性. 0x02 测试 常见有5个位置即:select * from admin where id=1[位置一]union[位置二]se ...