2555: SubString

Time Limit: 30 Sec  Memory Limit: 512 MB
Submit: 2548  Solved: 762

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

【分析】

  一开始都没想着用LCT,后来发现我的SAM的right数组一直都是要逆拓扑序求的。

  在线的话,还要在线维护。把pre边看成一棵树,就是要支持link,cut操作的,求子树和的东西。

  其实LCT我只会做路径的,不会做子树了。看了hzwer的代码。【然后好像是,其实也是维护了路径,就是link x和f 的时候就是把f到根的路径都加上val[x]

  【ORZ欧颓果说用splay维护dfs序也可以啊?

  1. #include<cstdio>
  2. #include<cstdlib>
  3. #include<cstring>
  4. #include<iostream>
  5. #include<algorithm>
  6. using namespace std;
  7. #define Maxn 600010
  8. #define Maxl 3000010
  9.  
  10. struct node
  11. {
  12. int pre,son[],step;
  13. }t[Maxn*];
  14.  
  15. struct nnode
  16. {
  17. int son[],fa,val,laz;
  18. nnode() {son[]=son[]=fa=val=laz=;}
  19. }tr[Maxn*];
  20.  
  21. char s[Maxl];
  22. void init(int mask)
  23. {
  24. scanf("%s",s);
  25. int l=strlen(s);
  26. for(int i=;i<l;i++)
  27. {
  28. mask=(mask*+i)%l;
  29. swap(s[i],s[mask]);
  30. }
  31. }
  32.  
  33. struct lct
  34. {
  35. void add(int x,int y)
  36. {
  37. if(x) tr[x].val+=y,tr[x].laz+=y;
  38. }
  39. bool is_root(int x)
  40. {
  41. return tr[tr[x].fa].son[]!=x&&tr[tr[x].fa].son[]!=x;
  42. }
  43. bool pushdown(int x)
  44. {
  45. int lc=tr[x].son[],rc=tr[x].son[];
  46. if(tr[x].laz)
  47. {
  48. add(lc,tr[x].laz);add(rc,tr[x].laz);
  49. tr[x].laz=;
  50. }
  51. }
  52. void rot(int x)
  53. {
  54. int fa=tr[x].fa,yy=tr[fa].fa;
  55. int w=tr[tr[x].fa].son[]==x;
  56.  
  57. if(!is_root(fa))
  58. {
  59. if(tr[yy].son[]==fa) tr[yy].son[]=x;
  60. else tr[yy].son[]=x;
  61. }tr[x].fa=yy;
  62.  
  63. tr[fa].son[-w]=tr[x].son[w];
  64. tr[tr[x].son[w]].fa=fa;
  65.  
  66. tr[x].son[w]=fa;
  67. tr[fa].fa=x;
  68. //upd(fa);//upd(x);
  69. }
  70. int q[*Maxn];
  71. void pre(int x)
  72. {
  73. int tp=;
  74. while(!is_root(x)) q[++tp]=x,x=tr[x].fa;
  75. q[++tp]=x;
  76. for(int i=tp;i>=;i--) pushdown(q[i]);
  77. }
  78. void splay(int x)
  79. {
  80. pre(x);
  81. while(!is_root(x))
  82. {
  83. int fa=tr[x].fa,yy=tr[fa].fa;
  84. if(!is_root(fa))
  85. {
  86. if((tr[yy].son[]==fa)==(tr[fa].son[]==x)) rot(fa);
  87. else rot(x);
  88. }
  89. rot(x);
  90. }//upd(x);
  91. }
  92. void access(int x)
  93. {
  94. int t=;
  95. while(x)
  96. {
  97. splay(x);
  98. tr[x].son[]=t;
  99. t=x;
  100. x=tr[x].fa;
  101. }
  102. }
  103. /*void split(int x,int y)
  104. {
  105. make_root(x);
  106. access(y);
  107. splay(y);
  108. }*/
  109. void link(int x,int f)
  110. {
  111. tr[x].fa=f;
  112. access(f);
  113. splay(f);
  114. add(f,tr[x].val);
  115. }
  116. void cut(int x)
  117. {
  118. access(x);splay(x);
  119. add(tr[x].son[],-tr[x].val);
  120. tr[tr[x].son[]].fa=;
  121. tr[x].son[]=;
  122. }
  123. }lct;
  124.  
  125. int mask;
  126. struct sam
  127. {
  128. int last,tot;
  129. void extend(int k)
  130. {
  131. int np=++tot,p=last;
  132. t[np].step=t[p].step+;
  133. tr[np].val=;
  134. while(p&&!t[p].son[k])
  135. {
  136. t[p].son[k]=np;
  137. p=t[p].pre;
  138. }
  139. if(!p) t[np].pre=,lct.link(np,);
  140. else
  141. {
  142. int q=t[p].son[k];
  143. if(t[q].step==t[p].step+) t[np].pre=q,lct.link(np,q);
  144. else
  145. {
  146. int nq=++tot;//upd(tot);
  147. t[nq].step=t[p].step+;
  148. memcpy(t[nq].son,t[q].son,sizeof(t[nq].son));
  149. t[nq].pre=t[q].pre;
  150. lct.link(nq,t[nq].pre);
  151. t[q].pre=t[np].pre=nq;
  152. lct.cut(q);lct.link(q,nq);lct.link(np,nq);
  153. while(p&&t[p].son[k]==q)
  154. {
  155. t[p].son[k]=nq;
  156. p=t[p].pre;
  157. }
  158. }
  159. }
  160. last=np;
  161. }
  162. void add()
  163. {
  164. init(mask);
  165. int l=strlen(s);
  166. for(int i=;i<l;i++) extend(s[i]-'A'+);
  167. }
  168. int query()
  169. {
  170. init(mask);
  171. int nw=,l=strlen(s);
  172. for(int i=;i<l;i++)
  173. {
  174. int ind=s[i]-'A'+;
  175. if(!t[nw].son[ind]) return ;
  176. nw=t[nw].son[ind];
  177. }
  178. lct.splay(nw);
  179. return tr[nw].val;
  180. }
  181. }sam;
  182.  
  183. char ss[];
  184.  
  185. int main()
  186. {
  187. int q;
  188. scanf("%d",&q);
  189. sam.tot=sam.last=;
  190. scanf("%s",s);
  191. int l=strlen(s);
  192. for(int i=;i<l;i++) sam.extend(s[i]-'A'+);
  193. while(q--)
  194. {
  195. scanf("%s",ss);
  196. if(ss[]=='A') sam.add();
  197. else
  198. {
  199. int ans=sam.query();
  200. printf("%d\n",ans);
  201. mask^=ans;
  202. }
  203. }
  204. return ;
  205. }

2017-04-19 07:48:14

【BZOJ 2555】 2555: SubString (SAM+LCT)的更多相关文章

  1. bzoj 2555 SubString(SAM+LCT)

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

  2. 【BZOJ 4170】 4170: 极光 (CDQ分治)

    4170: 极光 Time Limit: 30 Sec  Memory Limit: 512 MBSubmit: 121  Solved: 64 Description "若是万一琪露诺(俗 ...

  3. 【BZOJ 4527】 4527: K-D-Sequence (线段树)

    4527: K-D-Sequence Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 145  Solved: 59 Description 我们称一个 ...

  4. 【BZOJ 2982】 2982: combination (卢卡斯定理)

    2982: combination Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 510  Solved: 316 Description LMZ有n个 ...

  5. 【BZOJ 3262】 3262: 陌上花开 (CDQ分治)

    3262: 陌上花开 Description 有n朵花,每朵花有三个属性:花形(s).颜色(c).气味(m),又三个整数表示.现要对每朵花评级,一朵花的级别是它拥有的美丽能超过的花的数量.定义一朵花A ...

  6. 【bzoj 3333】排队计划(线段树)

    n个数,求一次逆序对.接着有m次修改操作,把每次输入的位置p的数之后<=它的数取出来,从小到大排序后再放回空位里,求逆序对.(N,M<=500,000 , Ai<=10^9)思路:1 ...

  7. 2019.03.01 bzoj2555: SubString(sam+lct)

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

  8. 【BZOJ】4721: [Noip2016]蚯蚓 / 【洛谷】P2827 蚯蚓(单调队列)

    Description 本题中,我们将用符号[c]表示对c向下取整,例如:[3.0」= [3.1」=[3.9」=3.蛐蛐国最近蚯蚓成灾了!隔壁跳 蚤国的跳蚤也拿蚯蚓们没办法,蛐蛐国王只好去请神刀手来帮 ...

  9. 【LOJ#3097】[SNOI2019]通信(费用流)

    [LOJ#3097][SNOI2019]通信(费用流) 题面 LOJ 题解 暴力就直接连\(O(n^2)\)条边. 然后分治/主席树优化连边就行了. 抄zsy代码,zsy代码是真的短 #include ...

随机推荐

  1. java多线程机制2(安全问题)

    线程状态图: ================================================================================= /* * 线程安全问题 ...

  2. 针对移动设备的CSS3布局

    针对移动设备的CSS3布局 一些专业人士预测五年内移动设备将击败普通电脑成为网页浏览领域的霸主,不管这个预言是否应验,让网页在移动设备上较好的显示已经成为网页设计师和开发者的重要任务,本教程学习用CS ...

  3. javascript中各类的prototype属性

    prototype 作用:获取调用对象的对象原型引用 应用:可以为某对象原型添加方法 例: function getMax() { var max = this[0]; for(var x=0; x& ...

  4. 20155117王震宇 2006-2007-2 《Java程序设计》第二周学习总结

    学号 2006-2007-2 <Java程序设计>第X周学习总结 教材学习内容总结 学习一门语言首先要熟悉基础的语法,注意不要和之前学过的语言知识混淆. java严格区分大小写. 教材学习 ...

  5. NB二人组(一)----堆排序

    堆排序前传--树与二叉树简介 特殊且常用的树--二叉树  两种特殊的二叉树 二叉树的存储方式 二叉树小结 堆排序 堆这个玩意....... 堆排序过程: 构造堆: 堆排序的算法程序(程序需配合着下图理 ...

  6. Vue 传递

    今天刷了一遍Vue的API,做个小笔记 父子传递数据时,父组件里标记要传的数据,子组件里用props获取,子组件用$emit('func',args)发布事件,父组件用@func接收. 方法一 par ...

  7. Problem D. Berland Railroads Gym - 101967D (思维)

    题目链接:https://cn.vjudge.net/contest/274029#problem/D 题目大意:给你0-9每个数的个数,然后让你找出最大的数,满足的条件是任意三位相连的都能被三整除. ...

  8. android 自定义View属性

    在android开发过程中,用到系统的View时候可以通过XML来定义一些View的属性.比如ImageView:   android:src  和android:scaleType为ImageVie ...

  9. spring-boot 更换依赖版本

    创建Spring Boot操作步骤如下: 在File菜单里面选择 New > Project,然后选择Spring Initializr 更换版本 或 pom spring-boot-start ...

  10. 14 - 函数参数检测-inspect模块

    目录 1 python类型注解 2 函数定义的弊端 3 函数文档 4 函数注解 4.1 annotation属性 5 inspect模块 5.1 常用方法 5.2 signature类 5.3 par ...