【BZOJ1014】火星人(Splay,哈希)
【BZOJ1014】火星人(Splay,哈希)
题面
题解
要动态维护这个串,一脸的平衡树。
那么用\(Splay\)维护这个哈希值就好了。
每次计算答案的时候二分+Splay计算区间哈希值,
时间复杂度\(O(nlog^2n)\)
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define ull unsigned long long
#define ll long long
#define RG register
#define MAX 111111
#define ls (t[x].ch[0])
#define rs (t[x].ch[1])
const int base=2333;
inline int read()
{
RG int x=0,t=1;RG char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
char ch[MAX];
ull pw[MAX];
int root,tot;
struct Node
{
int ch[2],ff,size,len;
ull v,Hash;
}t[MAX];
void pushup(int x)
{
t[x].size=t[ls].size+t[rs].size+1;
t[x].len=t[ls].len+t[rs].len+(x>2);
t[x].Hash=(t[ls].Hash*base+t[x].v)*pw[t[rs].len]+t[rs].Hash;
}
void rotate(int x)
{
int y=t[x].ff,z=t[y].ff;
int k=t[y].ch[1]==x;
t[z].ch[t[z].ch[1]==y]=x;t[x].ff=z;
t[y].ch[k]=t[x].ch[k^1];t[t[x].ch[k^1]].ff=y;
t[x].ch[k^1]=y;t[y].ff=x;
pushup(y);
}
void Splay(int x,int goal)
{
while(t[x].ff!=goal)
{
int y=t[x].ff,z=t[y].ff;
if(z!=goal)
(t[z].ch[0]==y)^(t[y].ch[0]==x)?rotate(x):rotate(y);
rotate(x);
}
if(!goal)root=x;pushup(x);
}
int Kth(int k)
{
int x=root;
while(233)
{
if(t[ls].size+1==k)return x;
if(t[ls].size+1<k)k-=t[ls].size+1,x=rs;
else x=ls;
}
}
ull Hash(int l,int len)
{
int L=Kth(l),R=Kth(l+len+1);
Splay(L,0);Splay(R,L);
return t[t[R].ch[0]].Hash;
}
int LCQ(int x,int y)
{
int l=0,r=tot-max(x,y)-1,ret=0;
while(l<=r)
{
int mid=(l+r)>>1;
if(Hash(x,mid)==Hash(y,mid))l=mid+1,ret=mid;
else r=mid-1;
}
return ret;
}
void insert(int x,int v)
{
int L=Kth(x+1),R=Kth(x+2);
Splay(L,0);Splay(R,L);
t[++tot].v=v;t[R].ch[0]=tot;
t[tot].ff=R;Splay(tot,0);
}
void Modify(int x,int v)
{
int L=Kth(x),R=Kth(x+2);
Splay(L,0);Splay(R,L);
t[t[R].ch[0]].v=v;pushup(t[R].ch[0]);
pushup(R);pushup(L);
}
int main()
{
pw[0]=1;for(int i=1;i<MAX;++i)pw[i]=pw[i-1]*base;
scanf("%s",ch+1);
t[1].ch[1]=2;t[2].ff=1;tot=2;root=1;pushup(2);pushup(1);
for(int i=1,l=strlen(ch+1);i<=l;++i)insert(i-1,ch[i]);
int Q=read(),x,y;
while(Q--)
{
scanf("%s",ch);
if(ch[0]=='Q')printf("%d\n",LCQ(read(),read()));
else if(ch[0]=='R'){x=read();scanf("%s",ch);y=ch[0];Modify(x,y);}
else{x=read();scanf("%s",ch);y=ch[0];insert(x,y);}
}
return 0;
}
【BZOJ1014】火星人(Splay,哈希)的更多相关文章
- BZOJ1014火星人prefix Splay維護序列 + 字符串哈希
@[Splay, 哈希] Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:\(madamimadam\), 我们将这个字符串的各个字符予以标号 ...
- 无旋Treap - BZOJ1014火星人 & 可持久化版文艺平衡树
!前置技能&概念! 二叉搜索树 一棵二叉树,对于任意子树,满足左子树中的任意节点对应元素小于根的对应元素,右子树中的任意节点对应元素大于根对应元素.换言之,就是满足中序遍历为依次访问节点对应元 ...
- BZOJ1014 JSOI2008火星人(splay+哈希)
splay维护哈希值即可. #include<iostream> #include<cstdio> #include<cmath> #include<cstd ...
- BZOJ1014:[JSOI2008]火星人(Splay,hash)
Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:madamimadam, 我们将这个字符串的各个字符予以标号:序号: 1 2 3 4 5 6 ...
- bzoj 1014 [JSOI2008]火星人prefix——splay+哈希
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1014 用splay维护字符串,每个点记录子树的哈希值,然后二分查询. 二分不是把两个点的哈希 ...
- bzoj1014 火星人 (hash+splay+二分答案)
求公共前缀的问题可以用hash+二分来解决,但这个是动态的,所以我们用平衡树来维护区间的hash值 复杂度$O(mlog^2n)$ #include<bits/stdc++.h> #def ...
- 【JSOI2008】火星人prefix 哈希 非旋转treap
题目大意 就是给你一个字符串,有三种操作,共\(m\)个 \(Q~x~y\):询问第\(x\)个后缀和第\(y\)个后缀的LCP \(R~x~y\):把第\(x\)个字符改成\(y\) \(I~x~y ...
- BZOJ.1014.[JSOI2008]火星人(Splay 二分 Hash)
题目链接 后缀数组显然不行啊.求LCP还可以哈希+二分,于是考虑用平衡树维护哈希值. \[某一节点的哈希值 = hs[lson]*base^{sz[rson]+1} + s[rt]*base^{sz[ ...
- bzoj1014火星人
...强迫症终于A了这道题 bzoj前30道全A指日可待 splay维护这个结点控制的字符串的hash值 每次旋转重新算一遍就可以了 查询的时候跑一个二分 讲起来很简单但是还是调了1h才调对了spl ...
- 【BZOJ1125】【POI2008】poc - splay+哈希
题意: Description n列火车,每条有l节车厢.每节车厢有一种颜色(用小写字母表示).有m次车厢交换操作.求:对于每列火车,在交换车厢的某个时刻,与其颜色完全相同的火车最多有多少. Inpu ...
随机推荐
- phpcms 的模板更换
刚安装完成后的phpcms ,自带的默认模板样式一般,可以自己换模板 首先打开phpcms文件夹,按照下图路径打开 default是存模板的文件夹 在里面新建一个文件夹 在default中主要用到的是 ...
- javaweb(八)——HttpServletResponse对象(二)
一.HttpServletResponse常见应用——生成验证码 1.1.生成随机图片用作验证码 生成图片主要用到了一个BufferedImage类, 生成随机图片范例: 1 package gacl ...
- 二、利用EnterpriseFrameWork快速开发Web系统(B/S)
EnterpriseFrameWork框架实例源代码下载: 实例下载 本章通过一个开发实例来讲解Web系统的开发经过,以及会碰到的一些问题.实例功能就是业务系统中最常见的增.删.改.查来演示,用一个界 ...
- 八、EnterpriseFrameWork框架基础功能之自定义报表
本章写关于框架中的“自定义报表”,类似上章“字典管理”也是三部分功能组成,包括配置报表.对报表按角色授权.查看报表:其核心思想就是实现新增一个报表而不用修改程序代码.不用升级,只需要编写一个存储过程, ...
- java 多路分发
1.概念 一个函数处理多种类型,其实和多态差不多. 但是要处理两种或者多种类型的数据时,就需要判断每种类型以及每种类型所对应的处理.(PS:我只是在走别人的老路,网上一搜这种概念,博客一大堆,我不知道 ...
- leetcode- 将有序数组转换为二叉搜索树(java)
将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树. 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1. 示例: 给定有序数组: [-10,-3,0, ...
- python程序设计——面向对象程序设计:方法
类中定义的方法分为四类:公有方法,私有方法,静态方法,类方法 公有方法.私有方法都属于对象,私有方法的名字以"__"开始 每个对象都有自己的公有方法和私有方法,这两类方法可以访问属 ...
- Elasticsearch 统计代码例子
aggs avg 平均数 最近15分钟的平均访问时间,upstream_time_ms是每次访问时间,单位毫秒 { "query": { "filtered": ...
- sql server block如何查询并kill
本帖提供两种做法,可避免在 SQL Server 事务锁定时产生的不正常或长时间阻塞,让用户和程序也无限期等待,甚至引起 connection pooling 连接数超过容量. 所谓的「阻塞」,是指当 ...
- 进阶系列(8)——匿名方法与lambda表达式
一 匿名方法的介绍 匿名方法是为了简化委托的实现,方便调用委托方法而出现的,同时,匿名方法也是学好lambda表达式的基础.在委托调用的方法中,如果方法只被调用一次,这个时候我们就没有必要创建 ...