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

用 splay 维护字符串上不同位置的哈希值还是第一次...

具体就是每个节点作为位置被不断旋转,点上维护的哈希值就是此时它及其儿子这一段区间的哈希值;

要查询 LCQ,可以二分一个长度,然后把两端区间分别旋转到根,取出哈希值比较;

据说用模数会很慢,写自然溢出比较好;

因为忘记 rotate 最后要 pushup 而调了很久...注释里是另一种可以A的 rotate - splay 系列;

又加深了对 splay 的理解,它的节点表示位置关系...

代码如下:

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstring>
  4. #include<algorithm>
  5. #define mid ((l+r)>>1)
  6. using namespace std;
  7. typedef unsigned long long ll;
  8. int const xn=1e5+,xm=;
  9. int n,m,rt,fa[xm],c[xm][],siz[xm];
  10. ll pw[xm],hsh[xm];
  11. char s[xn],ch[xn];
  12. void pushup(int x)
  13. {
  14. int ls=c[x][],rs=c[x][];
  15. siz[x]=siz[ls]+siz[rs]+;
  16. hsh[x]=hsh[ls]*pw[siz[rs]+]+(s[x]-'a'+)*pw[siz[rs]]+hsh[rs];
  17. }
  18. void rotate(int x,int &f)
  19. {
  20. int y=fa[x],z=fa[y],d=(c[y][]==x);
  21. if(z)c[z][c[z][]==y]=x;
  22. // if(y==f)f=x; else c[z][c[z][1]==y]=x;
  23. fa[x]=z; fa[y]=x; fa[c[x][!d]]=y;
  24. c[y][d]=c[x][!d]; c[x][!d]=y;
  25. pushup(y); pushup(x);//!!!
  26. }
  27. void splay(int x,int f)//
  28. {
  29. while(fa[x]!=f)//
  30. {
  31. int y=fa[x],z=fa[y];
  32. if(z!=f)//
  33. {
  34. if((c[y][]==x)^(c[z][]==y))rotate(x,f);
  35. else rotate(y,f);
  36. }
  37. rotate(x,f);
  38. }
  39. if(!f)rt=x;
  40. }
  41. void build(int l,int r,int lst)
  42. {
  43. if(l>r)return;
  44. if(l==r)hsh[l]=s[l]-'a'+,siz[l]=;
  45. else build(l,mid-,mid),build(mid+,r,mid);
  46. fa[mid]=lst; c[lst][mid>lst]=mid; pushup(mid);
  47. }
  48. int find(int x,int k)//找到 k 位置
  49. {
  50. while()
  51. {
  52. int p=c[x][],q=c[x][];
  53. if(siz[p]+==k)return x;
  54. else if(siz[p]+<k)x=q,k-=siz[p]+;
  55. else x=p;
  56. }
  57. }
  58. void insert(int pos,char d)
  59. {
  60. s[++n]=d; hsh[n]=d-'a'+;
  61. int x=find(rt,pos+);//+1 因为有左右的'a'
  62. splay(x,); x=find(rt,pos+); splay(x,rt);//
  63. // splay(x,rt); x=find(rt,pos+2); splay(x,c[rt][1]);
  64. c[x][]=n; siz[n]=; fa[n]=x;
  65. pushup(x); pushup(rt);
  66. }
  67. void change(int pos,char d)
  68. {
  69. int x=find(rt,pos+);
  70. splay(x,);//
  71. // splay(x,rt);
  72. s[x]=d; pushup(x);
  73. }
  74. bool ck(int l,int r,int k)
  75. {
  76. ll h1=,h2=;
  77. // int x=find(rt,l); splay(x,rt);//
  78. // x=find(rt,l+k+1); splay(x,c[rt][1]);
  79. // x=c[rt][1];//
  80. int x=find(rt,l); splay(x,);
  81. x=find(rt,l+k+); splay(x,rt);
  82. h1=hsh[c[x][]];
  83. // x=find(rt,r); splay(x,rt);//
  84. // x=find(rt,r+k+1); splay(x,c[rt][1]);
  85. // x=c[rt][1];//
  86. x=find(rt,r); splay(x,);
  87. x=find(rt,r+k+); splay(x,rt);
  88. h2=hsh[c[x][]];
  89. return h1==h2;
  90. }
  91. int query(int x,int l,int r)
  92. {
  93. int ll=,rr=n--max(l,r)+,ret=;
  94. while(ll<=rr)
  95. {
  96. int md=((ll+rr)>>);
  97. if(ck(l,r,md))ret=md,ll=md+;
  98. else rr=md-;
  99. }
  100. return ret;
  101. }
  102. void init()
  103. {
  104. n=strlen(s+); pw[]=;
  105. for(int i=;i<=xm-;i++)pw[i]=pw[i-]*;
  106. s[]=s[n+]='a';
  107. build(,n+,); n=n+; rt=(n+)/;//
  108. }
  109. int main()
  110. {
  111. scanf("%s",s+); init();
  112. scanf("%d",&m);
  113. for(int i=,x,y;i<=m;i++)
  114. {
  115. scanf("%s%d",ch,&x);
  116. if(ch[]=='I')scanf("%s",ch),insert(x,ch[]);
  117. if(ch[]=='R')scanf("%s",ch),change(x,ch[]);
  118. if(ch[]=='Q')scanf("%d",&y),printf("%d\n",query(rt,x,y));
  119. }
  120. return ;
  121. }

bzoj 1014 火星人prefix —— splay+hash的更多相关文章

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

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

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

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

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

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

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

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

  5. $bzoj1014-JSOI2008$ 火星人$prefix$ $splay$ $hash$

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

  6. BZOJ 1014 火星人prefix

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

  7. [BZOJ]1014 火星人prefix(JSOI2008)

    一边听省队dalao讲课一边做题真TM刺激. BZOJ的discuss简直就是题面plus.大样例.SuperHINT.dalao题解的结合体. Description 火星人最近研究了一种操作:求一 ...

  8. bzoj 1014 火星人prefix - 链表 - 分块

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

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

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

随机推荐

  1. hdu 1496 hash

    hash?判重,是否一样?相等?等式!没有想到,这次题做玩后,学到了HASH这一功能!当数据量在数组允许大小范围内时候即可!判断等式俩边是否相等,从而获得解的个数!从复杂度,n*m*k****,降到 ...

  2. Delphi:解决重绘造成的窗体闪烁问题

    解决窗体闪烁问题 具体代码: 1.在声明窗体类时加入:   private     procedure CreateParams(var Params: TCreateParams); overrid ...

  3. Python高级进阶(二)Python框架之Django写图书管理系统(LMS)

    正式写项目准备前的工作 Django是一个Web框架,我们使用它就是因为它能够把前后端解耦合而且能够与数据库建立ORM,这样,一个Python开发工程师只需要干自己开发的事情就可以了,而在使用之前就我 ...

  4. java Map集合对比分析

    1.Map:Map是所有map集合的顶级父接口,用于key/value形式的键值对,其中每一个key都映射到一个值,key不能重复. 2.TreeMap:该map将存储的键值对进行默认排序,并且还能够 ...

  5. 在SUSE12中使用 Machinery 进行高级系统管理

    简单介绍 在 SUSE Linux Enterprise 12 中.SUSE 如今推出了面向系统管理员的 Machinery.作为其高级系统管理模块的一部分.Machinery 是适用于 Linux ...

  6. [TypeScript] Query Properties with keyof and Lookup Types in TypeScript

    The keyof operator produces a union type of all known, public property names of a given type. You ca ...

  7. HTC 328T 提示手机存储不足 out of space怎么办

    不要再用什么软件做优化,做清理,都是治标不治本啊. 1 用豌豆荚备份数据   2 手机恢复出厂设置   3 用豌豆荚恢复数据

  8. 我的第一个开源控件-DragGridView

    我的第一个开源控件出炉了,希望各个小伙伴给个star,支持下.项目地址 1. 前言 因为项目须要,要做一个相似腾讯视频.频道管理.拖拽排序的效果.这个控件是在原地址 之上改造出来的.先看下效果图. 1 ...

  9. MVC架构在游戏开发中的应用

    一 定义 MVC即Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写. MVC是一种"前端"的设计模式. MV ...

  10. RabbitMQ常用命令、管理界面

    1.运行CMD,cd切换到RabbitMQ安装目录sbin下E:\Program Files\RabbitMQ Server\rabbitmq_server-3.7.2\sbin 执行 rabbitm ...