Time Limit: 30 Sec  Memory Limit: 512 MB
Submit: 2430  Solved: 719

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

Ctsc模拟赛By 洁妹

字符串 后缀自动机 + LCT

离线问子串出现次数的话,只需要在自动机上从底到顶更新fa结点的size,再回答询问即可。

如果要在线维护,那么每次新建一个结点,就需要从这个结点沿fa指针上溯,把经过的结点size都加1。

当数据很大的时候,这样暴力维护显然会T

然而似乎题目原本的数据比较弱,导致暴力操作并不会达到复杂度上界,甚至跑得比正解快……

数据加强以后,就只能写正解了。

我们需要一个能在树上区间加值的数据结构,同时要支持SAM的建中继结点操作。就决定是LCT了。

于是这就变成了一道考LCT的码农题……

蠢蠢地花了两晚上调过了样例,不过调过样例就直接A了也是带感。

マジやばくね

  1 /*by SilverN*/
  2 #include<algorithm>
  3 #include<iostream>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<cmath>
  7 #include<vector>
  8 using namespace std;
  9 const int mxn=1100010;
 10 struct LCT{
 11     int ch[mxn][2],fa[mxn];
 12     int val[mxn],mk[mxn];
 13     bool rev[mxn];
 14     int st[mxn],top;
 15     inline bool isroot(int x){
 16         return (ch[fa[x]][0]!=x)&&(ch[fa[x]][1]!=x);
 17     }
 18     inline void PD(int x){
 19         if(mk[x]){
 20             int &lc=ch[x][0],&rc=ch[x][1];
 21             mk[lc]+=mk[x];mk[rc]+=mk[x];
 22             val[lc]+=mk[x];val[rc]+=mk[x];
 23             mk[x]=0;
 24         }
 25         if(rev[x]){
 26             int &lc=ch[x][0],&rc=ch[x][1];
 27             swap(lc,rc);
 28             rev[lc]^=1;rev[rc]^=1;
 29             rev[x]^=1;
 30         }
 31         return;
 32     }
 33     void rotate(int x){
 34         int y=fa[x],z=fa[y],lc,rc;
 35         if(ch[y][0]==x)lc=0;else lc=1; rc=lc^1;
 36         if(!isroot(y)){
 37             ch[z][ch[z][1]==y]=x;
 38         }
 39         fa[x]=z;fa[y]=x;
 40         fa[ch[x][rc]]=y;
 41         ch[y][lc]=ch[x][rc];
 42         ch[x][rc]=y;
 43         return;
 44     }
 45     void Splay(int x){
 46         st[top=1]=x;
 47         for(int i=x;!isroot(i);i=fa[i])st[++top]=fa[i];
 48         while(top)PD(st[top--]);
 49         while(!isroot(x)){
 50             int y=fa[x],z=fa[y];
 51             if(!isroot(y)){
 52                 if((ch[y][0]==x)^(ch[z][0]==y))rotate(x);
 53                 else rotate(y);
 54             }
 55             rotate(x);
 56         }
 57         return;
 58     }
 59     void access(int x){
 60         for(int y=0;x;x=fa[x]){
 61             Splay(x);
 62             ch[x][1]=y;
 63             y=x;
 64         }
 65         return;
 66     }
 67     void link(int x,int y){
 68         fa[x]=y;access(y);Splay(y);
 69         val[y]+=val[x];mk[y]+=val[x];
 70         return;
 71     }
 72     void cut(int x,int y){
 73         access(y);Splay(y);
 74         if(ch[y][0]==x){
 75             fa[x]=ch[y][0]=0;
 76             val[x]-=val[y];mk[x]-=val[y];
 77         }
 78         return;
 79     }
 80     inline int query(int x){
 81         access(x);Splay(x);
 82         return val[x];
 83     }
 84 }Lt;
 85 struct SAM{
 86     int t[mxn][26],fa[mxn],l[mxn],sz[mxn];
 87     int S,last,cnt;
 88     void init(){S=last=cnt=1;return;}
 89     void add(int c){
 90         int p=last,np=++cnt;last=np;
 91         l[np]=l[p]+1;
 92         Lt.val[np]=1;
 93         sz[np]++;
 94         for(;p && !t[p][c];p=fa[p]){
 95             t[p][c]=np;
 96         }
 97         if(!p){
 98             fa[np]=S;
 99             Lt.link(np,S);
100         }
101         else{
102             int q=t[p][c];
103             if(l[q]==l[p]+1){
104                 fa[np]=q;
105                 Lt.link(np,q);
106             }
107             else{
108                 int nq=++cnt;
109                 l[nq]=l[p]+1;
110                 memcpy(t[nq],t[q],sizeof t[q]);
111                 //
112                 Lt.link(nq,fa[q]);
113                 Lt.cut(fa[q],q);
114                 Lt.link(np,nq);
115                 Lt.link(q,nq);
116                 //
117                 fa[nq]=fa[q];
118                 fa[q]=fa[np]=nq;
119                 for(;p && t[p][c]==q;p=fa[p]){
120                     t[p][c]=nq;
121                 }
122             }
123         }
124         return;
125     }
126     int query(char *s){
127         int len=strlen(s);
128         int now=S;
129         for(int i=0;i<len;i++){
130             if(t[now][s[i]-'A']){
131                 now=t[now][s[i]-'A'];
132             }
133             else return 0;
134         }
135         return Lt.query(now);
136     }
137 }sa;
138 char s[3000002],op[10];
139 void decode(char *c,int mask){//解码
140     int len=strlen(s);
141     for(int j=0;j<len;j++){
142         mask=(mask*131+j)%len;
143         char t=c[j];
144         c[j]=c[mask];
145         c[mask]=t;
146     }
147     return;
148 }
149 int Q,tlen,mask=0;
150 int main(){
151     int i,j;
152     scanf("%d",&Q);
153     scanf("%s",s);
154     sa.init();
155     int len=strlen(s);tlen=len;
156     for(i=0;i<len;i++) sa.add(s[i]-'A');
157     while(Q--){
158         scanf("%s%s",op,s);
159         decode(s,mask);//解码
160         if(op[0]=='A'){
161             int len=strlen(s);
162             tlen+=len;
163             for(i=0;i<len;i++){
164                 sa.add(s[i]-'A');
165             }
166         }
167         else{
168             int res=sa.query(s);
169             mask^=res;
170             printf("%d\n",res);
171         }
172     }
173     return 0;
174 }
175 

转载于:https://www.cnblogs.com/SilverNebula/p/6648688.html

Bzoj2555 SubString相关推荐

  1. 2019.03.01 bzoj2555: SubString(sam+lct)

    传送门 题意简述: 要求在线支持两个操作 (1):在当前字符串的后面插入一个字符串 (2):询问字符串s在当前字符串中出现了几次?(作为连续子串) 思路: 考虑用lctlctlct来动态维护samsa ...

  2. PKUSC2018训练日程(4.18~5.30)

    (总计:共66题) 4.18~4.25:19题 4.26~5.2:17题 5.3~5.9: 6题 5.10~5.16: 6题 5.17~5.23: 9题 5.24~5.30: 9题 4.18 [BZO ...

  3. 【bzoj2555】Substring【后缀平衡树入门】

    传送门 (bzoj上不去我也很无奈啊) 题意:维护一个字符串,支持后面加字符串,给定串询问出现次数.强制在线. 数据范围:暴力跑不过 前置知识:重量平衡树 众所周知,平衡树都用了一些策略保证平衡. 平 ...

  4. Java substring使用时有哪些注意事项?

    首先,使用substring截取字符串时,可能会出现两种异常,分别是StringIndexOutOfBoundsException和NullPointerException. 即字符串索引越界异常 与 ...

  5. leetcode 30. Substring with Concatenation of All Words 与所有单词相关联的字串 滑动窗口法

    题目描述 给定一个字符串 s 和一些长度相同的单词 words.在 s 中找出可以恰好串联 words 中所有单词的子串的起始位置. You are given a string, s, and a ...

  6. leetcode Longest Substring with At Most Two Distinct Characters 滑动窗口法

    题目解析 代码如下 题目解析 这一题是一道会员的题目,题目介绍如下: Given a string, find the length of the longest substring T that c ...

  7. js中substr,substring,indexOf,lastIndexOf的用法

    js中substr,substring,indexOf,lastIndexOf等的用法 1.substr substr(start,length)表示从start位置开始,截取length长度的字符串 ...

  8. JavaScript中substr()和substring的区别

    例子: var letters = "abcdefg"; console.log(letters.substr(1,3))//结果为bcd console.log(letters. ...

  9. LeetCode.3-最长无重复字符子串(Longest Substring Without Repeating Characters)

    这是悦乐书的第341次更新,第365篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Medium级别的第2题Longest Substring Without Repeating Cha ...

最新文章

  1. 四年级下册英语计算机房和教师办公室的图片,PEP英语四年级下册-Unit-1思维导图及知识点梳理.pptx...
  2. javascript数组常用方法
  3. 【MySQL distinct的使用】如果指定了 SELECT DISTINCT,那么 ORDER BY 子句中的项就必须出现在选择列表中
  4. java dao 泛型的好处_java中泛型有什么作用
  5. windows下jenkins常见问题填坑
  6. Uploadify 配置错误信息提示
  7. C中的extern-static-const关键词
  8. PCB板设计流程总结
  9. python登录qq邮箱爬邮件_如何使用Python登录邮箱发送邮件
  10. 通达信l2行情接口怎么用?
  11. 量化感知训练_《量化健身 动作精讲》:专业解读健美身材的秘密
  12. 打开我的收藏夹 -- Python时间序列分析篇
  13. C/C++基础 hypot函数
  14. 独立站引流技巧和营销思路
  15. STM32F10xxx20xxx21xxxL1xxxx Cortex-M3程序设计手册 阅读笔记三(1):Cortex-M3指令集概要
  16. 互联网摸鱼日报(2023-04-30)
  17. 深度解析CentOS通过日志反查***
  18. 各种说明方法的答题格式_12种说明方法的答题格式
  19. docker内应用连接宿主机mysql
  20. 更新源linux命令,Linux更新源

热门文章

  1. Android线程实例讲解
  2. SSH协议、HTTPS中SSL协议的完整交互过程
  3. 弗罗里达州收税人接受比特币、比特币现金支付
  4. AppScan使用分享
  5. MongoDB的查询整理
  6. activiti no processes deployed with key
  7. Lync2013 恢复-整残之后如何重新安装
  8. ObjectDataSource未能找到带参数的非泛型方法的解决
  9. SQL Server误区30日谈-Day21-数据损坏可以通过重启SQL Server来修复
  10. JAVA游戏编程之三----j2me 手机游戏入门开发--俄罗斯方块_5_使用LUA脚本写游戏