bzoj 4545

给定一个踹树,支持几种操作。

  • 本质不同子串询问
  • 加入子树
  • 询问字符串\(S\) 在树上的出现次数。

好码好码

重点就是维护\(parent\) 树,考虑用\(LCT\)维护此树。

第三问就是匹配点的\(right\)集合大小,算一算就可以了。

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int MAXN = 200010;
  4. int read () {
  5. int q=0,f=1;char ch=getchar();
  6. while(!isdigit(ch)) {
  7. if(ch=='-')f=-1;ch=getchar();
  8. }
  9. while(isdigit(ch)){
  10. q=q*10+ch-'0';ch=getchar();
  11. }
  12. return q*f;
  13. }
  14. long long ans;
  15. int opt,x,y,n,q;
  16. struct LCT {
  17. int son[MAXN][2];
  18. int fa[MAXN];
  19. int v[MAXN];
  20. int tag[MAXN];
  21. int rev[MAXN];
  22. int getson(int x) {
  23. return son[fa[x]][1] == x;
  24. }
  25. int isroot(int x) {
  26. return son[fa[x]][0] != x and son[fa[x]][1] != x;
  27. }
  28. void down(int now) {
  29. swap(son[now][0],son[now][1]);
  30. rev[now] ^= 1;
  31. }
  32. void Add_val(int x,int k) {
  33. if(x) {
  34. v[x] += k;
  35. tag[x] += k;
  36. }
  37. }
  38. void pushdown(int now) {
  39. if(rev[now]) {
  40. down(son[now][0]);
  41. down(son[now][1]);
  42. rev[now] = 0;
  43. }
  44. if(tag[now]) {
  45. Add_val(son[now][0],tag[now]);
  46. Add_val(son[now][1],tag[now]);
  47. tag[now] = 0;
  48. }
  49. }
  50. void dfs(int now) {
  51. if(!isroot(now)) {
  52. dfs(fa[now]);
  53. }
  54. pushdown(now);
  55. }
  56. void rotate(int now) {
  57. int y = fa[now];
  58. int z = fa[y];
  59. int wht = getson(now);
  60. fa[now] = z;
  61. if(!isroot(y)) {
  62. son[z][y == son[z][1]] = now;
  63. }
  64. fa[son[now][wht ^ 1]] = y;
  65. son[y][wht] = son[now][wht ^ 1];
  66. fa[y] = now;
  67. son[now][wht ^ 1] = y;
  68. }
  69. void splay(int now) {
  70. dfs(now);
  71. for(int i = fa[now]; !isroot(now) ; rotate(now),i = fa[now]) {
  72. if(!isroot(i)) {
  73. rotate(getson(now) == getson(i) ? i : now);
  74. }
  75. }
  76. }
  77. void access(int now) {
  78. for(int i = 0;now;i = now,now = fa[now]) {
  79. splay(now);
  80. son[now][1] = i;
  81. }
  82. }
  83. void makeroot(int now) {
  84. access(now);
  85. splay(now);
  86. down(now);
  87. }
  88. void link(int x,int y) {
  89. makeroot(x);
  90. fa[x] = y;
  91. }
  92. void cut(int x,int y) {
  93. makeroot(x);
  94. access(y);
  95. splay(y);
  96. son[y][0] = fa[x] = 0;
  97. }
  98. void Add(int x,int y,int k) {
  99. makeroot(x);
  100. access(y);
  101. splay(y);
  102. Add_val(y,k);
  103. }
  104. int query(int now) {
  105. splay(now);
  106. return v[now];
  107. }
  108. }lct;
  109. struct SAM {
  110. int ch[MAXN][3];
  111. int len[MAXN];
  112. int fail[MAXN];
  113. int Cnt;
  114. SAM() {
  115. Cnt = 1;
  116. }
  117. int Copy(int c) {
  118. int now = ++Cnt;
  119. for(int i = 0;i <= 2; ++i) {
  120. ch[now][i] = ch[c][i];
  121. }
  122. return now;
  123. }
  124. void link(int x,int y) {
  125. fail[x] = y;
  126. lct.link(x,y);
  127. ans += len[x] - len[y];
  128. }
  129. int work(int p,int c) {
  130. int q = ch[p][c];
  131. int nq = Copy(q);
  132. len[nq] = len[p] + 1;
  133. lct.v[nq] = lct.query(q);
  134. lct.cut(q,fail[q]);
  135. ans -= len[q] - len[fail[q]];
  136. link(nq,fail[q]);
  137. link(q,nq);
  138. for( ; ch[p][c] == q ; p = fail[p]) {
  139. ch[p][c] = nq;
  140. }
  141. return nq;
  142. }
  143. int insert(int p,int c) {
  144. int cur;
  145. if(ch[p][c]) {
  146. cur = len[ch[p][c]] == len[p] + 1 ? ch[p][c] : work(p,c);
  147. }
  148. else {
  149. cur = ++Cnt;
  150. len[cur] = len[p] + 1;
  151. for( ; p and !ch[p][c] ; p = fail[p]) {
  152. ch[p][c] = cur;
  153. }
  154. if(!p) {
  155. link(cur,1);
  156. }
  157. else if(len[ch[p][c]] == len[p] + 1) {
  158. link(cur,ch[p][c]);
  159. }
  160. else {
  161. link(cur,work(p,c));
  162. }
  163. }
  164. lct.Add(cur,1,1);
  165. return cur;
  166. }
  167. }sam;
  168. struct graph {
  169. int head[MAXN];
  170. int cnt;
  171. graph () {
  172. cnt = 0;
  173. }
  174. int ver[MAXN];
  175. int nxt[MAXN];
  176. int val[MAXN];
  177. int vis[MAXN];
  178. int pos[MAXN];
  179. void add(int u,int v,int w) {
  180. ver[++cnt] = v;
  181. nxt[cnt] = head[u];
  182. head[u] = cnt;
  183. val[cnt] = w;
  184. }
  185. void Add(int u,int v,int w) {
  186. add(u,v,w);
  187. add(v,u,w);
  188. }
  189. void dfs(int now) {
  190. vis[now] = 1;
  191. for(int i = head[now];i;i=nxt[i]) {
  192. int y = ver[i];
  193. if(vis[y]) {
  194. continue;
  195. }
  196. pos[y] = sam.insert(pos[now],val[i]);
  197. dfs(y);
  198. }
  199. }
  200. }G;
  201. char s[MAXN];
  202. int main () {
  203. x = read(),n = read();
  204. for(int i = 1;i < n; ++i) {
  205. x = read(),y = read();
  206. scanf("%s",s);
  207. G.Add(x,y,s[0] - 'a');
  208. }
  209. G.pos[1] = 1;
  210. G.dfs(1);
  211. q = read();
  212. while(q--) {
  213. opt = read();
  214. if(opt == 1) {
  215. cout<<ans<<endl;
  216. }
  217. else if(opt == 2) {
  218. x = read(),y = read();
  219. for(int i = 1;i < y; ++i) {
  220. int X = read(),Y = read();
  221. scanf("%s",s);
  222. G.Add(X,Y,s[0] - 'a');
  223. }
  224. G.dfs(x);
  225. }
  226. else {
  227. scanf("%s",s);int len = strlen(s);
  228. int p = 1;
  229. int tag = 1;
  230. for(int i = 0;i < len; ++i) {
  231. if(!sam.ch[p][s[i] - 'a']) {
  232. cout<<0<<endl;
  233. tag = 0;
  234. break;
  235. }
  236. p = sam.ch[p][s[i] - 'a'];
  237. }
  238. if(tag) {
  239. cout<<lct.query(p)<<endl;
  240. }
  241. }
  242. }
  243. return 0;
  244. }

BZOJ 4545的更多相关文章

  1. bzoj 4545: DQS的trie

    Description DQS的自家阳台上种着一棵颗粒饱满.颜色纯正的trie. DQS的trie非常的奇特,它初始有n0个节点,n0-1条边,每条边上有一个字符.并且,它拥有极强的生长力:某个i时刻 ...

  2. bzoj 4545 DQS 的 Trie

    老年选手不会 SAM 也不会 LCT 系列 我的数据结构好菜啊 qnq 一颗 Trie 树,$q$ 次询问,每次可以是: 1.求这棵树上本质不同的子串数量 2.插入一个子树,保证总大小不超过 $100 ...

  3. BZOJ 2127: happiness [最小割]

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1815  Solved: 878[Submit][Status][Di ...

  4. BZOJ 3275: Number

    3275: Number Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 874  Solved: 371[Submit][Status][Discus ...

  5. BZOJ 2879: [Noi2012]美食节

    2879: [Noi2012]美食节 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1834  Solved: 969[Submit][Status] ...

  6. bzoj 4610 Ceiling Functi

    bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...

  7. BZOJ 题目整理

    bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...

  8. 【sdoi2013】森林 BZOJ 3123

    Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负整数 ...

  9. 【清华集训】楼房重建 BZOJ 2957

    Description 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些 ...

随机推荐

  1. AcWing 313. 花店橱窗 (线性DP)打卡

    题目:https://www.acwing.com/problem/content/315/ 题意:有一个矩阵,你需要在每一行选择一个数,必须保证前一行的数的下标选择在下一行的左边,即下标有单调性,然 ...

  2. Outlets

    Outlets Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  3. 嵌入式开发环境搭建(一) 虚拟机实现桥接Ethernet网口 并且通过WIFI进行NAT联网

    背景: 目前手头上有一块JZ2440的板子,之前有搭建完整套开发环境,由于虚拟机故障需要从新搭建服务器端,故在此记录搭建步骤 环境: Ubuntu16.4 VMWare 12 先行条件: 先按照自定义 ...

  4. 使用命令将ipa包上传到蒲公英

    参考:官文文档 请根据开发者自己的账号,将其中的 uKey 和 _api_key 的值替换为相应的值.   curl -F "file=@/Users/chenpeisong/Desktop ...

  5. Eclipse Luna安装Hibernate Tools 4.2.3不显示,设置Eclipse运行的JDK

    Eclipse Luna安装Hibernate Tools 4.2.3不显示,设置Eclipse运行的JDK,有需要的朋友可以参考下. eclipse-jee-luna-SR2中安装Hibernate ...

  6. dex2jar反编译大文件内存溢出的问题

    @echo off REM better invocation scripts for windows from lanchon, release in public domain. thanks! ...

  7. 强哥新周报SQL

    因为数据口径的更改,所以.强哥的SQL 比较好用.不会出麻烦. 总共有四个 日常记录下,好好看. -- 2019年4月核销新客 SELECT yzm2.consignee_phone AS `会员手机 ...

  8. USACO 5.5 章节

    Picture 题目大意 IOI 1998 求n (<=5000)个矩形 覆盖的图形 的周长(包括洞), 坐标范围[-10000,10000] 题解 一眼离散化+2维线段树,但仔细一想 空间不太 ...

  9. automate sap遇上的一些问题

    1. get column name of SAPGuiTable columnCount = SAPGuiSession("Session").SAPGuiWindow(&quo ...

  10. 使用自编译的Emacs26.0.50build10版本,helm报错(已解决)

    使用自编译的Emacs26.0.50build10版本,helm报错(已解决) */--> code {color: #FF0000} pre.src {background-color: #0 ...