原题链接:\(luogu\)$\ \ $ \(BZOJ\)$\ \ $ \(LOJ\)

题目大意:有一个可以支持插入和修改的字符串,定义函数 \(\operatorname{LCQ(x,y)}\) 表示从 \(x\) 开始的后缀与从 \(y\) 开始的后缀的最长公共前缀。


声明变量:

\(ls\):左儿子

\(rs\):右儿子

\(val\):平衡树维护变量,此题指字符 -'a'

\(sz\):子树大小

\(rk\):对应堆值

\(hs\):哈希值,后面会讲

\(pq\):哈希对应要乘的数字


考虑既然是求最长公共前缀,当然可以通过二分长度来求,用哈希维护即可。

要支持插入和修改,很显然可以用平衡树的 \(FHQ\ Treap\) 进行区间维护。

在原先 \(FHQ\) 需要维护的五个量的基础上,加入 \(hs\),表示其子树内的 \(hash\) 值。

转移方程即为:\(hs[x]=hs[ls[x]]+val[x]\times pq[sz[ls[x]]]+hs[rs[x]]\times pq[sz[ls[x]]+1]\)

插入修改按 \(FHQ\) 原先操作即可


代码:

#include<bits/stdc++.h>
#define ls(x) pl[x].ls
#define rs(x) pl[x].rs
#define val(x) pl[x].val
#define sz(x) pl[x].sz
#define rk(x) pl[x].rk
#define hs(x) pl[x].hs
#define ull unsigned long long
using namespace std;
struct fhq{
int ls,rs,val,sz,rk;ull hs;
}pl[100005];
int fhq_fail;
ull q=1145141,pq[250005];
int make_node(int x){
int a=++fhq_fail;
pl[a]={0,0,x,1,rand(),x};
return a;
}struct fhq_treap{
int rt,x,y,z;fhq_treap(){rt=x=y=z=0;}
void pushup(int p){
sz(p)=sz(ls(p))+sz(rs(p))+1;
hs(p)=hs(ls(p))+val(p)*pq[sz(ls(p))]+hs(rs(p))*pq[sz(ls(p))+1];
}void split(int p,int a,int &x,int &y){
if(!p){x=y=0;return;}
if(sz(ls(p))<a) x=p,split(rs(p),a-sz(ls(p))-1,rs(p),y);
else y=p,split(ls(p),a,x,ls(p));pushup(p);
}int merge(int x,int y){
if(!x||!y) return x+y;
if(rk(x)<rk(y)){
rs(x)=merge(rs(x),y);
pushup(x);return x;
}ls(y)=merge(x,ls(y));
pushup(y);return y;
}void add(int a,int b){
split(rt,a,x,y);
rt=merge(merge(x,make_node(b)),y);
}void change(int a,int b){
split(rt,a,x,z);split(x,a-1,x,y);
val(y)=hs(y)=b;rt=merge(merge(x,y),z);
}ull ghs(int l,int r){
split(rt,r-1,x,z);split(x,l-1,x,y);
ull re=hs(y);rt=merge(merge(x,y),z);return re;
}
}a;int n,m;string s;
int main(){
ios::sync_with_stdio(0);cin.tie(0);
srand(19820422);cin>>s>>m;
n=s.size();pq[0]=1;
for(int i=1;i<=n+m;i++) pq[i]=pq[i-1]*q;
for(int i=0;s[i];i++) a.rt=a.merge(a.rt,make_node(s[i]-'a'));
while(m--){
char c;int x;cin>>c>>x;
if(c=='Q'){
int y;cin>>y;if(x>y) swap(x,y);
int l=1,r=sz(a.rt)-y+1,ans=0;
while(l<=r){
int mid=(l+r)/2;
if(a.ghs(x,x+mid)==a.ghs(y,y+mid))
l=mid+1,ans=mid;else r=mid-1;
}cout<<ans<<"\n";continue;
}char d;cin>>d;
if(c=='R') a.change(x,d-'a');
else a.add(x,d-'a');
}return 0;
}//Kaká

[JSOI2008]火星人 题解的更多相关文章

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

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

  2. 【bzoj1014】[JSOI2008]火星人prefix

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

  3. BZOJ 1014: [JSOI2008]火星人prefix Splay+二分

    1014: [JSOI2008]火星人prefix 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=1014 Description 火星人 ...

  4. JSOI2008 火星人prefix

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

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

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

  6. 1014: [JSOI2008]火星人prefix

    1014: [JSOI2008]火星人prefix Time Limit: 10 Sec Memory Limit: 162 MB Description 火星人最近研究了一种操作:求一个字串两个后缀 ...

  7. BZOJ 1014: [JSOI2008]火星人prefix [splay 二分+hash] 【未完】

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

  8. bzoj 1014: [JSOI2008]火星人prefix hash && splay

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

  9. 求帮看!!!!BZOJ 1014 [JSOI2008]火星人prefix

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

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

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

随机推荐

  1. 销讯通CRM系统如何管理医药代表的销售过程

    医药行业的销售代表与其他行业的销售代表在专业知识要求.客户群体.销售流程.以及行业特性等方面都存在明显的区别,他们必须具备更高的专业素养和综合能力. CRM(客户关系管理系统)在医药行业中对于管理医药 ...

  2. uniapp安卓在线更新版本

    实现逻辑 通过获取线上的版本号和app的版本号进行对比 查看是不是最新版 - app版本号小于线上版本号则不是最新版 提示更新 模拟检测更新请求 起一个服务,也就是检测更新的接口 返回值为最新版本号和 ...

  3. 鸿蒙NEXT开发案例:世界时间表

    [引言] 本案例将展示如何使用鸿蒙NEXT框架开发一个简单的世界时钟应用程序.该应用程序能够展示多个城市的当前时间,并支持搜索功能,方便用户快速查找所需城市的时间信息.在本文中,我们将详细介绍应用程序 ...

  4. IOS多线程之NSOperation(2)

    IOS多线程之NSOperation(2) 最大并发数 open var maxConcurrentOperationCount: Int 并发数就是同时执行的任务数.比如,同时开3个线程执行3个任务 ...

  5. Qt开发经验小技巧176-180

    QCamera中获取设备的配置参数比如支持的分辨率集合等,需要先调用load后才能正确获取,或者关联stateChanged信号中判断状态是否是ActiveState,然后再读取. //方法1:调用l ...

  6. Qt音视频开发35-Onvif图片参数

    一.前言 视频中的图片的配置参数一般有亮度.饱和度.对比度.锐度等,以前一直以为这些需要通过厂家的私有协议SDK来设置才行,后面通过研究Onvif Device Manager 和 Onvif Dev ...

  7. Intellij IDEA开发环境中Springboot项目无Run ****main()的菜单

    问题描述: Intellij  IDEA开发环境中Springboot项目无Run ****main()的菜单. 解决办法有以下几种: 方法1:Idea无右键run选项, 无法通过main方法启动sp ...

  8. IM开发者的零基础通信技术入门(十一):为什么WiFi信号差?一文即懂!

    一.本文内容概述 WiFi对于现在的家庭来说,属于司空见惯的上网方式,但很多情况下,家里房间多.空间大.杂物乱的情况下,WiFi的信号就受影响.为什么WiFi信号会受影响?什么情况下该使用何种方式组网 ...

  9. GeoServer简介

    GeoServer简介 GeoServer的地图服务主要通过以下几个层次进行组织 工作区(Workspace):工作区是GeoServer中的顶级组织单位,通常用于区分不同的项目或用户.每个工作区可以 ...

  10. 当github遇到了Halloween,神奇的彩蛋出现了!

    往年每个万圣节github都会修改配色方案,今天才发现,so记录这个不平凡的2020年的github的彩蛋,希望一切都会慢慢好起来.