【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 ... 
随机推荐
- Java SE教程
			第0讲 开山篇 读前介绍:本文中如下文本格式是超链接,可以点击跳转 >>超链接<< 我的学习目标:基础要坚如磐石 代码要十份规范 笔记要认真详实 一.java内容介绍 ... 
- MAVEN相关文章
			Maven入门指南① :Maven 快速入门及简单使用 Maven入门指南② :Maven 常用命令,手动创建第一个 Maven 项目 Maven入门指南③:坐标和依赖 Maven入门指南④:仓库 M ... 
- 手撕一个 Galgame 神器——Shub-Niggurath Project
			一.想法 Galgame 我们大概可以分为好用的 Galgame 和好玩的 Galgame,但是如果你把好玩的 Galgame 拿来用的话,有时候会十分让人着急.如果你躺在床上,一只手还在按压键盘实际 ... 
- java读取excel或者csv时日期格式数据处理
			背景:最近写一个通过excel批量导入数据的功能,里面含有时间,但是java读取之后把时间转为了距离1990年1月1号的天数,比如excel中时间为2018/9/16 18:30,java读取之后变成 ... 
- hashlib模块使用详情
			python常用模块目录 一:hashlib简介 1.什么叫hash:hash是一种算法(不同的hash算法只是复杂度不一样)(3.x里代替了md5模块和sha模块,主要提供 SHA1, SHA224 ... 
- dubbo源码分析1——负载均衡
			dubbo中涉及到的负载均衡算法只要有四种:Random LoadBalance(随机均衡算法).RoundRobin LoadBalance(权重轮循均衡算法).LeastAction LoadBa ... 
- Tomcat配置 —— server.xml
			Tomcat的核心组件是servlet容器. Tomcat各个组件之间的嵌套关系 server.xml配置如下: <Server port="8005" shutdown=& ... 
- java使用匿名类直接new接口
			翻看Vector代码的时候,看到这么一段. /** * Returns an enumeration of the components of this vector. The * returned ... 
- 转 maven3常用命令、java项目搭建、web项目搭建详细图解
			转自地址:http://blog.csdn.net/edward0830ly/article/details/8748986 ------------------------------maven3常 ... 
- linux之JDK安装
			1.JDK安装 a.卸载JDK (1)卸载默认的JDK 用root用户登陆到系统,打开一个终端输入 # rpm -qa|grep gcj 显示内容其中包含下面两行信息 # java-1.4.2-gcj ... 
