经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C++ » 查看文章
BZOJ1014: [JSOI2008]火星人prefix(splay 二分 hash)
来源:cnblogs  作者:自为风月马前卒  时间:2018/11/30 9:38:52  对本文有异议

题意

题目链接

Sol

一眼splay + 二分hash,不过区间splay怎么写来着呀

试着写了两个小时发现死活不对

看了一下yyb的代码发现自己根本就不会splay。。。。

  1. // luogu-judger-enable-o2
  2. #include<bits/stdc++.h>
  3. #define ull unsigned long long
  4. using namespace std;
  5. const int MAXN = 1e6 + 10;
  6. const ull base = 27;
  7. inline int read() {
  8. char c = getchar(); int x = 0, f = 1;
  9. while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
  10. while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
  11. return x * f;
  12. }
  13. int N, M;
  14. char s[MAXN];
  15. int root, tot, ch[MAXN][2], fa[MAXN], siz[MAXN];
  16. ull ha[MAXN], val[MAXN], po[MAXN];
  17. bool rev[MAXN];
  18. int ident(int x) {
  19. return ch[fa[x]][1] == x;
  20. }
  21. void connect(int x, int f, int id) {
  22. fa[x] = f; ch[f][id] = x;
  23. }
  24. void update(int x) {
  25. siz[x] = siz[ch[x][0]] + siz[ch[x][1]] + 1;
  26. ha[x] = ha[ch[x][0]] + val[x] * po[siz[ch[x][0]]] + po[siz[ch[x][0]] + 1] * ha[ch[x][1]];
  27. }
  28. void rotate(int x) {
  29. int y = fa[x], R = fa[y], Yson = ident(x), Rson = ident(y);
  30. int B = ch[x][Yson ^ 1];
  31. connect(x, R, Rson); connect(B, y, Yson); connect(y, x, Yson ^ 1);
  32. update(y); update(x);
  33. }
  34. void splay(int x, int to) {
  35. //to = fa[to];
  36. while(fa[x] != to) {
  37. if(fa[fa[x]] == to) rotate(x);
  38. else if(ident(x) == ident(fa[x])) rotate(fa[x]), rotate(x);
  39. else rotate(x), rotate(x);
  40. }
  41. if(!to) root = x; update(x);
  42. }
  43. int find(int k) {
  44. int x = root;
  45. while(1) {
  46. if(siz[ch[x][0]] + 1 == k) return x;
  47. if(siz[ch[x][0]] + 1 < k) k -= siz[ch[x][0]] + 1, x = ch[x][1];//tag
  48. else x = ch[x][0];
  49. }
  50. }
  51. ull gethash(int l, int len) {
  52. int x = find(l), y = find(l + len + 1);
  53. splay(x, 0); splay(y, x);
  54. return ha[ch[y][0]];
  55. }
  56. int LCP(int y, int x) {
  57. int l = 0, r = tot - max(x, y) - 1, ans = 0;
  58. while(l <= r) {
  59. int mid = l + r >> 1;
  60. if(gethash(x, mid) == gethash(y, mid)) l = mid + 1, ans = mid;
  61. else r = mid - 1;
  62. }
  63. return ans;
  64. }
  65. void insert(int x, int v) {
  66. int l = find(x + 1), r = find(x + 2);
  67. splay(l, 0); splay(r, l);
  68. val[++tot] = v; fa[tot] = r; ch[r][0] = tot; splay(tot, 0);
  69. }
  70. void change(int x, int v) {
  71. int l = find(x), r = find(x + 2);
  72. splay(l, 0); splay(r, l);
  73. val[ch[r][0]] = v; update(ch[r][0]);
  74. update(r); update(l);
  75. }
  76. int main() {
  77. // freopen("a.in", "r", stdin);freopen("a.out", "w", stdout);
  78. po[0] = 1;
  79. for(int i = 1; i <= (int)1e5; i++) po[i] = base * po[i - 1];
  80. scanf("%s", s + 1); N = strlen(s + 1);
  81. ch[1][1] = 2; fa[2] = 1; tot = 2; root = 1; update(2); update(1);
  82. for(int i = 1; i <= N; i++)
  83. insert(i - 1, s[i]);
  84. int M = read();
  85. while(M--) {
  86. char opt[3]; scanf("%s", opt);
  87. if(opt[0] == 'Q') {int x = read(), y = read(); printf("%d\n", LCP(x, y));}
  88. else if(opt[0] == 'R') {
  89. int x = read(); scanf("%s", opt + 1);
  90. change(x, opt[1]);
  91. } else {
  92. int x = read(); scanf("%s", opt + 1);
  93. insert(x, opt[1]);
  94. }
  95. }
  96. return 0;
  97. }
  98. /*
  99. */
 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号