题目大意:一个字符串三个操作:①求两个后缀的LCP②插入一个字符③修改一个字符。

  前几天刚学了hash+二分求lcp,就看到这题。

  原来splay还能这么用?!原来splay模板这么好写?我以前写的splay是假的吧woc

  splay每个节点代表一个字符,并维护这个子树代表一个子串的哈希值。因为splay旋转不破坏树结构,所以不论怎么旋转这棵splay树都能代表这个字符串。

  预处理处理少了调了半天呜呜呜

  赶紧跑去更新自己的splay模板

  1. #include<iostream>
  2. #include<cstring>
  3. #include<cstdlib>
  4. #include<cstdio>
  5. #define which(x) (son[fa[x]][1]==x)
  6. #define ull unsigned long long
  7. using namespace std;
  8. const int maxn=;
  9. int n,m,x,y,tot,root;
  10. int fa[maxn],son[maxn][],size[maxn],s[maxn];
  11. ull hs[maxn],mul[maxn];
  12. char st[maxn],ch[maxn],ch2[maxn];
  13. void read(int &k)
  14. {
  15. int f=;k=;char c=getchar();
  16. while(c<''||c>'')c=='-'&&(f=-),c=getchar();
  17. while(c<=''&&c>='')k=k*+c-'',c=getchar();
  18. k*=f;
  19. }
  20. void update(int x)
  21. {
  22. size[x]=size[son[x][]]+size[son[x][]]+;
  23. hs[x]=hs[son[x][]]+mul[size[son[x][]]]*s[x]+mul[size[son[x][]]+]*hs[son[x][]];
  24. }
  25. void rotate(int x)
  26. {
  27. int f=fa[x];
  28. bool k=which(x);
  29. son[f][k]=son[x][!k];
  30. son[x][!k]=f;
  31. son[fa[f]][which(f)]=x;
  32. fa[son[f][k]]=f;
  33. fa[x]=fa[f];
  34. fa[f]=x;
  35. size[x]=size[f];
  36. hs[x]=hs[f];
  37. update(f);
  38. }
  39. void splay(int x,int g)
  40. {
  41. while(fa[x]!=g)
  42. {
  43. int f=fa[x];
  44. if(fa[f]==g)
  45. {
  46. rotate(x);
  47. break;
  48. }
  49. if(which(x)^which(f))rotate(x);
  50. else rotate(f);
  51. rotate(x);
  52. }
  53. if(!g)root=x;
  54. }
  55. int rank(int x,int k)
  56. {
  57. if(k<=size[son[x][]])return rank(son[x][],k);
  58. else if(k==(size[son[x][]]+))return x;
  59. else return rank(son[x][],k-size[son[x][]]-);
  60. }
  61. int build(int l,int r,int f)
  62. {
  63. if(l>r)return ;
  64. int x=++tot,mid=(l+r)>>;
  65. fa[x]=f;s[x]=(int)(st[mid]-'a')+;
  66. son[x][]=build(l,mid-,x);
  67. son[x][]=build(mid+,r,x);
  68. update(x);
  69. return x;
  70. }
  71. void insert(int k,int ch)
  72. {
  73. int x=rank(root,k),y=rank(root,k+);
  74. splay(x,);splay(y,x);
  75. s[++tot]=ch;
  76. fa[tot]=y;son[y][]=tot;
  77. update(tot);update(y);update(x);
  78. }
  79. void change(int k,int ch)
  80. {
  81. int x=rank(root,k);
  82. splay(x,);
  83. s[x]=ch;
  84. update(x);
  85. }
  86. int lcp(int kx,int ky)
  87. {
  88. int l=,r=n;
  89. while(l<r)
  90. {
  91. int mid=(l+r+)>>;
  92. if(ky+mid>n+)
  93. {
  94. r=mid-;
  95. continue;
  96. }
  97. int x=rank(root,kx-),y=rank(root,kx+mid);
  98. splay(x,);splay(y,x);
  99. ull haxi=hs[son[y][]];
  100. x=rank(root,ky-),y=rank(root,ky+mid);
  101. splay(x,);splay(y,x);
  102. if(haxi==hs[son[y][]])l=mid;
  103. else r=mid-;
  104. }
  105. return l;
  106. }
  107. int main()
  108. {
  109. scanf("%s",st+);
  110. n=strlen(st+);
  111. mul[]=;
  112. for(int i=;i<=;i++)mul[i]=mul[i-]*;
  113. root=build(,n+,);
  114. read(m);
  115. for(int i=;i<=m;i++)
  116. {
  117. scanf("%s",ch);
  118. if(ch[]=='Q')
  119. {
  120. read(x);read(y);
  121. if(x>y)swap(x,y);
  122. if(x!=y)printf("%d\n",lcp(x+,y+));
  123. else printf("%d\n",n-x+);
  124. }
  125. if(ch[]=='R')
  126. {
  127. read(x);
  128. scanf("%s",ch2);
  129. change(x+,(int)(ch2[]-'a')+);
  130. }
  131. if(ch[]=='I')
  132. {
  133. read(x);
  134. scanf("%s",ch2);
  135. insert(x+,(int)(ch2[]-'a')+);
  136. n++;
  137. }
  138. }
  139. return ;
  140. }

bzoj1014: [JSOI2008]火星人prefix(splay+hash+二分)的更多相关文章

  1. bzoj1014: [JSOI2008]火星人prefix splay+hash+二分

    Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 ...

  2. 【bzoj1014】[JSOI2008]火星人prefix Splay+Hash+二分

    题目描述 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 8 9 10 ...

  3. BZOJ 1014 [JSOI2008]火星人prefix (Splay + Hash + 二分)

    1014: [JSOI2008]火星人prefix Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 8112  Solved: 2569[Submit] ...

  4. bzoj1014: [JSOI2008]火星人prefix splay+hash

    我写的代码好像自古以来就是bzoj不友好型的 本地跑的比std快,但是交上去巧妙被卡 答案...应该是对的,拍了好久了 #include <bits/stdc++.h> #define M ...

  5. 【BZOJ1014】[JSOI2008]火星人prefix Splay+hash

    [BZOJ1014][JSOI2008]火星人prefix Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个 ...

  6. BZOJ 1014: [JSOI2008]火星人prefix( splay + hash )

    用splay维护序列, 二分+hash来判断LCQ.. #include<bits/stdc++.h> using namespace std; typedef unsigned long ...

  7. P4036 [JSOI2008]火星人(splay+hash+二分)

    P4036 [JSOI2008]火星人 Splay维护hash,查询二分 $a[x].vl=a[lc].vl*ha[a[rc].sz+1]+a[x].w*ha[a[rc].sz]+a[rc].vl$ ...

  8. BZOJ1014: [JSOI2008]火星人prefix(splay 二分 hash)

    题意 题目链接 Sol 一眼splay + 二分hash,不过区间splay怎么写来着呀 试着写了两个小时发现死活不对 看了一下yyb的代码发现自己根本就不会splay.... // luogu-ju ...

  9. [BZOJ1014] [JSOI2008] 火星人prefix (splay & 二分答案)

    Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 ...

  10. BZOJ1014[JSOI2008]火星人prefix(splay维护hash)

    Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam,我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 7 ...

随机推荐

  1. hdu1010Tempter of the Bone(迷宫dfs+剪枝)

    Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Othe ...

  2. Vs2015 遇到 CL:fatal error c1510 cannot load language clui.dll

    网上说什么点击修复VS,修改VS的,经验证都不好使,直接下载这个库,放在system32/64下面皆可以了

  3. Windows运行机理——消息与消息队列

    Windows运行机理这系列文章都是来至于<零基础学Qt4编程>——吴迪,个人觉得写得很好,所以进行了搬运和个人加工 Windows程序设计时一种基于消息的时机驱动方式的设计模式,完全不同 ...

  4. GIt学习第一天之安装和版本库创建

    搬运自 ‘廖雪峰的官方网站’ 1.git安装 官网下载地址:https://git-scm.com/download/win   百度网盘下载地址:https://pan.baidu.com/s/1k ...

  5. 初学Direct X(4)

    初学Direct X(4) 本文学着做出一个如下的小游戏 游戏方式是使用键盘控制红色的Bucket收集蓝色的炸弹 1.酝酿一下 现在我已经掌握: 将位图文件加载到内存 绘制位图到buckbuffer ...

  6. 统计hive库表在具体下所有分区大小

    1 查询具体表分区大小,以字节展示 hadoop fs -du /user/hive/warehouse/treasury.db/dm_user_excercise > dm_user_exce ...

  7. lintcode 二叉树前序遍历

    二叉树的前序遍历    给出一棵二叉树,返回其节点值的前序遍历. 您在真实的面试中是否遇到过这个题? Yes 样例 给出一棵二叉树 {1,#,2,3}, 1 \ 2 / 3 返回 [1,2,3]. / ...

  8. JAVA基础学习之路(二)方法定义,重载,递归

    一,方法的定义: package test; public class test1 { public static void main(String args[]) { int result = ad ...

  9. truffle框架快速开发合约步骤

    矩阵元区块链智能合约开发指南 1 适用范围 本规范描述了矩阵元区块链系统智能合约的开发约束与规范,用以指导DAPP开发者按照本规范开发基于矩阵元区块链运行的应用. 2 术语解释 术语 术语解释 DAP ...

  10. maven 教程二 深入

    一:编写POM <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w ...