题意不赘述了,太清晰了。

说题解:首先根据原字符串建立SPT,首尾建议多加一个空白字符。

给一个树构图,按照平衡树的前后大小顺序性质可以使它们始终维持为一个序列,并且可以通过rank找到序列的第k个。

树构造完了以后,点插入,点修改,询问神马的代码里都有详细注释。

/*BZOJ 1014新手看的时候建议从main函数处开始,按照运行顺序来脑模拟。P.S. 这个代码的hash用的是自然溢出而非取mod运算。
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#define N 250010
#define is(x) (son[fa[x]][1]==x)
using namespace std;
typedef unsigned long long LL;
char start[N];
int digit[N];
LL power[N]={1};
struct node
{int root,n;LL hash[N];int val[N],fa[N],son[N][2],size[N];inline void update(int p){size[p]=size[son[p][0]]+size[son[p][1]]+1;hash[p]=hash[son[p][0]]*power[size[son[p][1]]+1]+val[p]*power[size[son[p][1]]]+hash[son[p][1]];/*此代码是得到53位制的hash值,hash[p]表示该段的hash值,想一下就很好理解。*/}inline void Build(int l,int r,int mid){if(l<mid)/*左边有数*/{int lmid=l+mid-1>>1;Build(l,mid-1,lmid);fa[lmid]=mid;son[mid][0]=lmid;}if(mid<r)/*右边有数*/{int rmid=mid+1+r>>1;Build(mid+1,r,rmid);fa[rmid]=mid;son[mid][1]=rmid;}val[mid]=digit[mid],update(mid);/*val表示当前字符(数字版)*/}inline void link(int x,int y,int d){son[y][d]=x;fa[x]=y;}inline void Rotate(int x){int y=fa[x],z=fa[y],id=is(x),t=son[x][!id];if(t)fa[t]=y;son[y][id]=t;link(x,z,is(y));link(y,x,!id);update(y);}inline void Splay(int x,int k){int y,z;while(fa[x]!=k){y=fa[x];z=fa[y];if(z==k){Rotate(x);break;}if(is(x)==is(y))Rotate(y),Rotate(x);else Rotate(x),Rotate(x);}update(x);if(!k)root=x;}inline int Select(int rank,int k)/*找到该节点并将它旋转到k的儿子处(k=0则旋到根)*/{if(size[root]<rank)return -1;/*找不到*/int x=root;while(size[son[x][0]]+1!=rank)/*循环条件:根不是要找的节点*/{if(size[son[x][0]]+1>rank)x=son[x][0];else rank=rank-size[son[x][0]]-1,x=son[x][1];}/*已经找到要找的节点*/Splay(x,k);return x;}inline void newnode(int &x,int y,int w){x=++n;son[x][0]=son[x][1]=0;val[x]=w;fa[x]=y;size[x]=1;}inline void Insert(int x,int p){int l=Select(x,0),r=Select(x+1,l);/*x到根,x+1到根的右子节点,即保证r的左子树为NULL*/newnode(son[r][0],r,p);Splay(n,0);}inline void Change(int x,int p){x=Select(x,0),val[x]=p,Splay(x,0);}inline bool check(int a,int b,int len){int x;Select(a-1,0);x=Select(a+len,root);/*把区间(此处为a开始的len个)rotate到lrt*/if(x==-1)return 0;LL hash1=hash[son[x][0]];Select(b-1,0);x=Select(b+len,root);if(x==-1)return 0;LL hash2=hash[son[x][0]];return hash1==hash2;}
}tree;
void handle()
{int i,m,l,r,mid,L,R;char a[5];for(int i=1;i<N;i++)power[i]=power[i-1]*53;scanf("%s",start);tree.n=strlen(start)+2;/*左右各添一个空白字符*/for(int i=2;i<=tree.n-1;i++)digit[i]=start[i-2]-'a'+1;tree.root=(1+tree.n)>>1,tree.Build(1,tree.n,1+tree.n>>1);/*建树*/scanf("%d",&m);for(int i=1;i<=m;i++){scanf("%s",a);/*下面l+1的缘故是因为序列左右各添了一个空白字符*/if(a[0]=='Q'){scanf("%d %d",&L,&R);l=0,r=tree.n;while(l<r){/*二分出解*/mid=l+r>>1;if(tree.check(L+1,R+1,mid))l=mid+1;else r=mid;}printf("%d\n",l-1);}else if(a[0]=='R'){scanf("%d %s",&l,a);tree.Change(l+1,a[0]-'a'+1);}else{scanf("%d %s",&l,a);tree.Insert(l+1,a[0]-'a'+1);}}
}
int main()
{
//  freopen("test.in","r",stdin);handle();return 0;
}
复制去Google翻译翻译结果

【BZOJ1014】【JSOI2008】火星人prefix Splay处理区间,hash+dichotomy(二分)check出解相关推荐

  1. BZOJ1014: [JSOI2008]火星人prefix

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

  2. 【BZOJ1014】【JSOI2008】火星人prefix Splay处理区间,hash+dichotomy(二分)check出解...

    题意不赘述了,太清晰了. 说题解:首先依据原字符串建立SPT.首尾建议多加一个空白字符. 给一个树构图,依照平衡树的前后大小顺序性质能够使它们始终维持为一个序列,而且能够通过rank找到序列的第k个. ...

  3. bzoj 1014: [JSOI2008]火星人prefix(splay维护区间+Hash+二分)

    1014: [JSOI2008]火星人prefix Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 7588  Solved: 2429 [Submi ...

  4. splay/fhq-treap 问卷调查反馈—— [JSOI2008]火星人prefix(splay),Strange Queries(fhq-treap)

    文章目录 [JSOI2008]火星人prefix Strange Queries [JSOI2008]火星人prefix BZOJ1014 思路很好想,哈希字符串即可 只是平衡树的码量大 注意因为sp ...

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

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

  6. bzoj 1014 火星人prefix —— splay+hash

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1014 用 splay 维护字符串上不同位置的哈希值还是第一次... 具体就是每个节点作为位置 ...

  7. BZOJ 1014 [JSOI2008]火星人prefix

    splay维护hash值: 看到大佬们都在打数据结构,我说好的不打数据结构又自己打脸了. 为了写这个昨天还特意去打了Splay的普通平衡树,自从我学会Treap以来第一次用splayA掉普通平衡树QA ...

  8. poj2002 poj3432 正方形个数 (hash,二分)

    给出一堆点,求其中正方形的个数. 题目很简单,如果枚举,复杂度为O(n^4),肯定超时,我们利用hash,或者二分来降低复杂度,枚举其中的两个点,然后利用正方形的性质求出其余的两个点,然后判断这两个点 ...

  9. Mysql 优化器内部JOIN算法hash join Nestloopjoin及classic hash join CHJ过程详解

    Mysql hash join之classic hash join CHJ过程详解 hash join的历史 优化器里的hash join算法在SQL Server.Oracle.postgress等 ...

最新文章

  1. JDK1.6.0下载安装与环境配置
  2. 离线轻量级大数据平台Spark之MLib机器学习库Word2Vec实例
  3. Bat命令:从Ftp获取文件以及数据导入
  4. java 验证码透明背景_Java中的证书透明度验证
  5. mysql timestamp 默认值是什么#039;_MYSQL中TIMESTAMP类型的默认值
  6. VSCode USER GUIDE Basic Editing
  7. 使用shadow dom封装web组件
  8. Swift - 使用xib添加新界面
  9. 游戏设计类毕业论文文献(推荐10篇)
  10. 《OpenCV3编程入门》毛星云编著
  11. 谷歌插件文档 镜像_最好的Google文档插件
  12. 华为路由器:ospf协议入门介绍
  13. win10 RTX30系列显卡 安装tensorflow-gpu 1.15
  14. python pdf脚本之家_Python实现简单拆分PDF文件的方法
  15. cocos2d-x 使用位图工具制作 fnt字体
  16. VR 中的常用指令设置及介绍
  17. 如何在MAC OS中使用HAXM?
  18. Ubuntu 10.10 最全的更新源收集(ubuntu yuan)
  19. 北京电信东区电信局 Excel人力资源应用培训
  20. 如何用水经注万能地图下载器进行投影转换

热门文章

  1. 教师节到了,用Python做了个非常好用的学生点名系统
  2. 洛谷——P2916 [USACO08NOV]为母牛欢呼Cheering up the Cows
  3. 极客日报:腾讯《王者荣耀》禁止未满12周岁用户充值;B站发布16款新品游戏;华为注册姚安娜商标被驳回
  4. C:\WINDOWS\system32\Macromed\Flash\Flash32_11_5_502_110.ocx
  5. 解决log4j2子线程无法获取到traceId问题
  6. 《迷你世界》亿级玩家都在用的游戏场景推荐系统长啥样?
  7. python对dataframe时序数据按时间顺序读取
  8. 我的未来,何去何从?
  9. 计算机校本培训心得,校本培训心得体会(通用3篇)
  10. python培训总结心得