题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1014

因为涉及到增加和修改,所以后缀数组就被pass掉了,想到的就是平衡树维护hash值,查询的时候就是二分相同的长度来比较,修改就是删除再增加。

这里使用的是无旋Treap

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. typedef unsigned int ull;
  5. const int maxn = ;
  6. int Siz[maxn], ls[maxn], rs[maxn], pos[maxn], val[maxn], root, cnt;
  7. ull Hash[maxn], w[maxn];
  8. inline void up(int x) {
  9. Siz[x] = Siz[ls[x]] + Siz[rs[x]] + ;
  10. w[x] = w[ls[x]] * Hash[Siz[rs[x]] + ] + Hash[Siz[rs[x]]] * val[x] + w[rs[x]];
  11. }
  12. inline void split_size(int x, int siz, int &A, int &B) {
  13. if (x == )return (void)(A = B = );
  14. if (siz <= Siz[ls[x]])
  15. B = x, split_size(ls[x], siz, A, ls[x]);
  16. else
  17. A = x, split_size(rs[x], siz - Siz[ls[x]] - , rs[x], B);
  18. up(x);
  19. }
  20. inline int Merge(int A, int B) {
  21. if (A == || B == )return A | B;
  22. int ans;
  23. if (pos[A] > pos[B])ans = A, rs[A] = Merge(rs[A], B);
  24. else ans = B, ls[B] = Merge(A, ls[B]);
  25. up(ans);
  26. return ans;
  27. }
  28. inline void insert(int x, char v) {
  29. int A, B;
  30. split_size(root, x, A, B);
  31. cnt++;
  32. w[cnt] = val[cnt] = v - 'a' + ;
  33. Siz[cnt] = ;
  34. pos[cnt] = rand();
  35. root = Merge(Merge(A, cnt), B);
  36. }
  37. inline void Delete(int x) {
  38. int A, B, C, D;
  39. split_size(root, x, A, B);
  40. split_size(A, x - , C, D);
  41. D = Merge(ls[D], rs[D]);
  42. root = Merge(Merge(C, D), B);
  43. }
  44. inline ull query(int l, int r) {
  45. int A, B, C, D;
  46. ull ans;
  47. split_size(root, l - , A, B);
  48. split_size(B, r - l + , C, D);
  49. ans = w[C];
  50. root = Merge(A, Merge(C, D));
  51. return ans;
  52. }
  53. inline bool check(int x, int y, int len) {
  54. return query(x, x + len - ) == query(y, y + len - );
  55. }
  56. inline int read() {
  57. int x = , f = ; char c = getchar();
  58. for (; !isdigit(c); c = getchar()) if (c == '-') f = -;
  59. for (; isdigit(c); c = getchar()) x = x * + c - ''; return x * f;
  60. }
  61. inline char cread() {
  62. char c = getchar();
  63. for (; !isalpha(c); c = getchar()); return c;
  64. }
  65. inline void reads(string& s) {
  66. char c = getchar();
  67. for (; !isalpha(c); c = getchar()); s = " ";
  68. for (; isalpha(c); c = getchar()) s += c;
  69. }
  70. string s;
  71. int main() {
  72. reads(s);
  73. int n = s.size() - , m;
  74. m = read();
  75. Hash[] = ;
  76. for (int i = ; i < maxn; i++)
  77. Hash[i] = Hash[i - ] * ;
  78. for (int i = ; i <= n; i++)
  79. insert(i, s[i]);
  80. while (m--) {
  81. char opt;
  82. int x, y;
  83. opt = cread();
  84. if (opt == 'Q') {
  85. x = read(), y = read();
  86. int l = , r = min(n - x, n - y) + , ans;
  87. while (l <= r) {
  88. int mid = l + r >> ;
  89. if (check(x, y, mid)) {
  90. ans = mid;
  91. l = mid + ;
  92. }
  93. else
  94. r = mid - ;
  95. }
  96. printf("%d\n", ans);
  97. }
  98. else if (opt == 'R') {
  99. x = read(), opt = cread();
  100. Delete(x);
  101. insert(x - , opt);
  102. }
  103. else {
  104. x = read(), opt = cread();
  105. n++;
  106. insert(x, opt);
  107. }
  108. }
  109. return ;
  110. }

[Bzoj1014][JSOI2008]火星人prefix(无旋Treap&hash)的更多相关文章

  1. BZOJ1014 JSOI2008 火星人prefix 【非旋转Treap】*

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

  2. [BZOJ1014][JSOI2008]火星人prefix

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

  3. 2018.06.28 BZOJ1014 [JSOI2008]火星人prefix(非旋treap+hash)

    [JSOI2008]火星人prefix Time Limit: 10 Sec Memory Limit: 162 MB Submit: 8951 Solved: 2860 Description 火星 ...

  4. bzoj千题计划106:bzoj1014 [JSOI2008]火星人prefix

    http://www.lydsy.com/JudgeOnline/problem.php?id=1014 两个后缀的最长公共前缀:二分+hash 带修改带插入:splay维护 #include< ...

  5. Jewel Magic UVA - 11996 || bzoj1014: [JSOI2008]火星人prefix

    Jewel Magic UVA - 11996 这是一道用splay/非旋treap做的题(这里用的是非旋treap) 1/2/3是splay/非旋treap的常规操作.对于操作4,可以用哈希法求LC ...

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

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

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

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

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

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

  9. bzoj1014: [JSOI2008]火星人prefix(splay+hash+二分)

    题目大意:一个字符串三个操作:①求两个后缀的LCP②插入一个字符③修改一个字符. 前几天刚学了hash+二分求lcp,就看到这题. 原来splay还能这么用?!原来splay模板这么好写?我以前写的s ...

随机推荐

  1. 用Node.js原生代码实现静态服务器

    ---恢复内容开始--- 后端中服务器类型有两种 1. web服务器[ 静态服务器 ] - 举例: wamp里面www目录 - 目的是为了展示页面内容 - 前端: nginx 2. 应用级服务器[ a ...

  2. 安装运行谷歌开源的TensorFlow Object Detection API视频物体识别系统

    Linux安装 参照官方文档:https://github.com/tensorflow/models/blob/master/research/object_detection/g3doc/inst ...

  3. Python Paramiko模块使用

    1 执行远程命令 #!/usr/bin/python import paramiko ssh = paramiko.SSHClient() ssh.set_missing_host_key_polic ...

  4. 定时器,定时发邮件JavaMail

    一.定时器用法: 1.1先导入jar包 <!--spring整合其他文件时要用的jar包--> <dependency> <groupId>org.springfr ...

  5. goland使用:导入一个github开源项目tidb

    概要:在windos下的IDEA 的go语言的编辑器 goland的使用,导入github上面的开源项目. 问题: 下载好goland之后,open project打开一个下载好的githubhub项 ...

  6. python笔记(1)--基础知识

    一.注释 单行注释 #打印“hello world” print("hello.world!") 另外一种单行注释 print("hello,world!") ...

  7. hdu 4845 : 拯救大兵瑞恩 (bfs+状态压缩)

    题目链接 #include<bits/stdc++.h> using namespace std; typedef long long LL; int n,m,p,s,k; ,,,-}; ...

  8. php stripos()函数 语法

    php stripos()函数 语法 作用:寻找字符串中某字符最先出现的位置,不区分大小写.直线电参数 语法:stripos(string,find,start) 参数: 参数 描述 string  ...

  9. luoguP4721 【模板】分治 FFT (分治NTT)

    给定 $g[1....n-1]$,求 $f[0],f[1],...,f[n-1]$,其中   $f[i]=\sum_{j=1}^{i}f[i-j]g[j]$    变界为 $f[0]=1$ 答案模 9 ...

  10. Python_011(生成器)

    一.生成器 def func(): ") return 222 ret = func() print(ret) #结果 111 222 1)这里面函数体里是返回值return;如果将retu ...