【BZOJ1014】火星人(Splay,哈希)

题面

BZOJ

题解

要动态维护这个串,一脸的平衡树。

那么用\(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,哈希)的更多相关文章

  1. BZOJ1014火星人prefix Splay維護序列 + 字符串哈希

    @[Splay, 哈希] Description 火星人最近研究了一种操作:求一个字串两个后缀的公共前缀.比方说,有这样一个字符串:\(madamimadam\), 我们将这个字符串的各个字符予以标号 ...

  2. 无旋Treap - BZOJ1014火星人 & 可持久化版文艺平衡树

    !前置技能&概念! 二叉搜索树 一棵二叉树,对于任意子树,满足左子树中的任意节点对应元素小于根的对应元素,右子树中的任意节点对应元素大于根对应元素.换言之,就是满足中序遍历为依次访问节点对应元 ...

  3. BZOJ1014 JSOI2008火星人(splay+哈希)

    splay维护哈希值即可. #include<iostream> #include<cstdio> #include<cmath> #include<cstd ...

  4. BZOJ1014:[JSOI2008]火星人(Splay,hash)

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

  5. bzoj 1014 [JSOI2008]火星人prefix——splay+哈希

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1014 用splay维护字符串,每个点记录子树的哈希值,然后二分查询. 二分不是把两个点的哈希 ...

  6. bzoj1014 火星人 (hash+splay+二分答案)

    求公共前缀的问题可以用hash+二分来解决,但这个是动态的,所以我们用平衡树来维护区间的hash值 复杂度$O(mlog^2n)$ #include<bits/stdc++.h> #def ...

  7. 【JSOI2008】火星人prefix 哈希 非旋转treap

    题目大意 就是给你一个字符串,有三种操作,共\(m\)个 \(Q~x~y\):询问第\(x\)个后缀和第\(y\)个后缀的LCP \(R~x~y\):把第\(x\)个字符改成\(y\) \(I~x~y ...

  8. BZOJ.1014.[JSOI2008]火星人(Splay 二分 Hash)

    题目链接 后缀数组显然不行啊.求LCP还可以哈希+二分,于是考虑用平衡树维护哈希值. \[某一节点的哈希值 = hs[lson]*base^{sz[rson]+1} + s[rt]*base^{sz[ ...

  9. bzoj1014火星人

    ...强迫症终于A了这道题  bzoj前30道全A指日可待 splay维护这个结点控制的字符串的hash值 每次旋转重新算一遍就可以了 查询的时候跑一个二分 讲起来很简单但是还是调了1h才调对了spl ...

  10. 【BZOJ1125】【POI2008】poc - splay+哈希

    题意: Description n列火车,每条有l节车厢.每节车厢有一种颜色(用小写字母表示).有m次车厢交换操作.求:对于每列火车,在交换车厢的某个时刻,与其颜色完全相同的火车最多有多少. Inpu ...

随机推荐

  1. logstash处理@timestamp时区

    input { stdin { } } filter { #ruby { # code => "event.set('timestamp', event.get('@timestamp ...

  2. EF6+MVC5之Oracleo数据库的CodeFirst方式实现

    http://www.oracle.com/technetwork/topics/dotnet/whatsnew/index.htm http://www.knowsky.com/887470.htm ...

  3. appium -- 页面出现弹窗,关闭后,无法识别页面元素(转)

    原文:https://www.cnblogs.com/leavescy/p/9733001.html; 1. 问题:如图所示:在修改手势密码的过程中,点击了返回按钮后,弹出该弹窗:点击继续设置后,就发 ...

  4. Scrapy爬豆瓣电影Top250并存入MySQL数据库

    d:进入D盘 scrapy startproject douban创建豆瓣项目 cd douban进入项目 scrapy genspider douban_spider movie.douban.co ...

  5. windows下Mysql安装启动及常用操作

    1.下载mysql https://dev.mysql.com/downloads/ 2.配置环境变量 变量名:MYSQL_HOME 变量值:E:\MySql\mysql-8.0.15-winx64\ ...

  6. 廖雪峰git笔记

    查看本地机子的在Git上的名字和邮箱:git config user.namegit config user.email 对所有仓库指定相同的用户名和Email地址:git config --glob ...

  7. jquery on函数和prop与attr区别

    一.jquery on()方法 1.语法 2.例子 $(document).ready(function(){ $("p").on("click",functi ...

  8. openstack-r版(rocky)搭建基于centos7.4 的openstack swift对象存储服务 一

    openstack-r版(rocky)搭建基于centos7.4 的openstack swift对象存储服务 一 openstack-r版(rocky)搭建基于centos7.4 的openstac ...

  9. 论文笔记:Visualizing and Understanding Convolutional Networks

    2014 ECCV 纽约大学 Matthew D. Zeiler, Rob Fergus 简单介绍(What) 提出了一种可视化的技巧,能够看到CNN中间层的特征功能和分类操作. 通过对这些可视化信息 ...

  10. Thunder团队——选题展示

    团队名称:Thunder 组长:王航 成员:李传康.代秋彤.邹双黛.苗威.宋雨.胡佑蓉.杨梓瑞 项目名称:爱阅app 视频展示: http://www.cnblogs.com/lick468/p/76 ...