前两篇讲述了SPLAY模板操作,这一篇稍微介绍一下SPLAY的实际应用

(其实只有一道题,因为本蒟蒻就写了这一个)

例:bzoj 1014火星人prefix

由于本蒟蒻不会后缀数组,所以题目中给的提示完全没看懂

不过并不影响我们做这道题,因为正解好像不用后缀数组...

首先,如果这题没有插入和修改,那么我们只需二分+hash即可

(很显然,二分相同前缀的长度,用hash检查是否合法)

可是这题有插入修改,单纯hash搞不了

所以我们应用SPLAY维护hash值即可

查找时同样二分

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#define ls tree[rt].lson
#define rs tree[rt].rson
#define ull unsigned int
#define seed 131
#define maxn 150000
using namespace std;
struct SPLAY
{
int lson;
int rson;
ull val;
ull typval;
int huge;
int fa;
}tree[150005];
ull p[150005];
int n,m;
char s[150005];
int cot=0;
int rot;
char tt[2];
void update(int rt)
{
tree[rt].huge=tree[ls].huge+tree[rs].huge+1;
tree[rt].val=tree[ls].val+p[tree[ls].huge+1]*tree[rs].val+tree[rt].typval*p[tree[ls].huge];
}
void buildtree(int l,int r,int f)
{
int mid=(l+r)>>1;
if(l==r)
{
tree[l].lson=tree[l].rson=0;
tree[l].typval=tree[l].val=s[l]-'a'+1;
tree[l].huge=1;
tree[l].fa=f;
}
tree[mid].typval=s[mid]-'a'+1;
tree[mid].fa=f;
if(l<mid)
{
buildtree(l,mid-1,mid);
}
if(r>mid)
{
buildtree(mid+1,r,mid);
}
update(mid);
if(mid<f)
{
tree[f].lson=mid;
}else
{
tree[f].rson=mid;
}
}
void rotate(int st,int &ed)
{
int v1=tree[st].fa;
int v2=tree[v1].fa;
int ltyp;
if(tree[v1].lson==st)
{
ltyp=0;
}else
{
ltyp=1;
}
if(v1==ed)
{
ed=st;
}else
{
if(tree[v2].lson==v1)
{
tree[v2].lson=st;
}else
{
tree[v2].rson=st;
}
}
if(ltyp)
{
tree[tree[st].lson].fa=v1;
tree[v1].fa=st;
tree[v1].rson=tree[st].lson;
tree[st].lson=v1;
tree[st].fa=v2;
}else
{
tree[tree[st].rson].fa=v1;
tree[v1].fa=st;
tree[v1].lson=tree[st].rson;
tree[st].rson=v1;
tree[st].fa=v2;
}
update(v1);
update(st);
}
void splay(int st,int &ed)
{
while(st!=ed)
{
int v1=tree[st].fa;
int v2=tree[v1].fa;
if(v1!=ed)
{
if((tree[v1].lson==st&&tree[v2].lson!=v1)||(tree[v1].rson==st&&tree[v2].rson!=v1))
{
rotate(st,ed);
}else
{
rotate(v1,ed);
}
}
rotate(st,ed);
}
}
int findf(int rt,int v)
{
if(tree[ls].huge+1==v)
{
return rt;
}else if(tree[ls].huge>=v)
{
return findf(ls,v);
}else
{
return findf(rs,v-1-tree[ls].huge);
}
}
int split(int st,int ed)
{
int v1=findf(rot,st);
int v2=findf(rot,ed);
splay(v1,rot);
splay(v2,tree[v1].rson);
return tree[v2].lson;
}
bool check(int st1,int st2,int len)
{
int v1=split(st1,st1+len+1);
ull tt=tree[v1].val;
int v2=split(st2,st2+len+1);
ull ty=tree[v2].val;
if(tt==ty)
{
return 1;
}else
{
return 0;
}
}
void ins(int st,int ed,int v)
{
int v1=split(st,ed);
tree[v1].typval=tree[v1].val=v;
update(tree[v1].fa);
update(tree[tree[v1].fa].fa);
}
void change(int st,int v)
{
int v1=findf(rot,st);
int v2=findf(rot,st+1);
splay(v1,rot);
splay(v2,tree[rot].rson);
cot++;
tree[cot].typval=tree[cot].val=v;
tree[cot].huge=1;
tree[v2].lson=cot;
tree[cot].fa=v2;
update(v2);
update(v1);
}
int divi(int lc,int rc,int st1,int st2)
{
int l=lc,r=rc;
while(l<=r)
{
int mid=(l+r)>>1;
if(check(st1,st2,mid))
{
l=mid+1;
}else
{
r=mid-1;
}
}
return r;
}
int main()
{
scanf("%s",s+2);
int l=strlen(s+2);
scanf("%d",&m);
p[0]=1;
for(int i=1;i<=maxn;i++)
{
p[i]=p[i-1]*seed;
}
buildtree(1,l+2,0);
cot=l+2;
rot=(l+3)>>1;
while(m--)
{
scanf("%s",tt);
if(tt[0]=='Q')
{
int lq,rq;
scanf("%d%d",&lq,&rq);
printf("%d\n",divi(1,min(cot-lq-1,cot-rq-1),lq,rq));
}else if(tt[0]=='R')
{
int x;
scanf("%d",&x);
scanf("%s",tt);
int d=tt[0]-'a'+1;
ins(x,x+2,d);
}else
{
int x;
scanf("%d",&x);
scanf("%s",tt);
int d=tt[0]-'a'+1;
change(x+1,d);
}
}
return 0;
}

SPLAY,LCT学习笔记(三)的更多相关文章

  1. LCT 学习笔记

    LCT学习笔记 前言 自己定的学习计划看起来完不成了(两天没学东西,全在补题),决定赶快学点东西 于是就学LCT了 简介 Link/Cut Tree是一种数据结构,我们用它解决动态树问题 但是LCT不 ...

  2. Oracle学习笔记三 SQL命令

    SQL简介 SQL 支持下列类别的命令: 1.数据定义语言(DDL) 2.数据操纵语言(DML) 3.事务控制语言(TCL) 4.数据控制语言(DCL)  

  3. [Firefly引擎][学习笔记三][已完结]所需模块封装

    原地址:http://www.9miao.com/question-15-54671.html 学习笔记一传送门学习笔记二传送门 学习笔记三导读:        笔记三主要就是各个模块的封装了,这里贴 ...

  4. JSP学习笔记(三):简单的Tomcat Web服务器

    注意:每次对Tomcat配置文件进行修改后,必须重启Tomcat 在E盘的DATA文件夹中创建TomcatDemo文件夹,并将Tomcat安装路径下的webapps/ROOT中的WEB-INF文件夹复 ...

  5. java之jvm学习笔记三(Class文件检验器)

    java之jvm学习笔记三(Class文件检验器) 前面的学习我们知道了class文件被类装载器所装载,但是在装载class文件之前或之后,class文件实际上还需要被校验,这就是今天的学习主题,cl ...

  6. VSTO学习笔记(三) 开发Office 2010 64位COM加载项

    原文:VSTO学习笔记(三) 开发Office 2010 64位COM加载项 一.加载项简介 Office提供了多种用于扩展Office应用程序功能的模式,常见的有: 1.Office 自动化程序(A ...

  7. Java IO学习笔记三

    Java IO学习笔记三 在整个IO包中,实际上就是分为字节流和字符流,但是除了这两个流之外,还存在了一组字节流-字符流的转换类. OutputStreamWriter:是Writer的子类,将输出的 ...

  8. NumPy学习笔记 三 股票价格

    NumPy学习笔记 三 股票价格 <NumPy学习笔记>系列将记录学习NumPy过程中的动手笔记,前期的参考书是<Python数据分析基础教程 NumPy学习指南>第二版.&l ...

  9. Learning ROS for Robotics Programming Second Edition学习笔记(三) 补充 hector_slam

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

  10. Learning ROS for Robotics Programming Second Edition学习笔记(三) indigo rplidar rviz slam

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS for Robotics Pr ...

随机推荐

  1. Nginx插件之openresty反向代理和日志滚动配置案例

    Nginx插件之openresty反向代理和日志滚动配置案例 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.openresty介绍 1>.Nginx介绍 Nginx是一款 ...

  2. Hadoop集群-HDFS集群中大数据运维常用的命令总结

    Hadoop集群-HDFS集群中大数据运维常用的命令总结 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本篇博客会简单涉及到滚动编辑,融合镜像文件,目录的空间配额等运维操作简介.话 ...

  3. iPhone电源键坏了怎么开机和关机?

    一.开机 1.将USB数据线插到iPhone上,此时先不要将另一头插到电脑上 2.长按Home键不要动 3.将数据线的另一头插到电脑上 这时iPhone就会自动开机 二.关机 1.进入设置找到“通用” ...

  4. 缓存穿透、雪崩、热点与Redis

    (拼多多问:Redis雪崩解决办法) 导读:互联网系统中不可避免要大量用到缓存,在缓存的使用过程中,架构师需要注意哪些问题?本文以 Redis 为例,详细探讨了最关键的 3 个问题. 一.缓存穿透预防 ...

  5. 基于Redis主从复制读写分离架构的Session共享(Windows Server)

    搭建主从复制 1.安装软件 下载Redis-x64-3.2.100.zip:https://github.com/MicrosoftArchive/redis/releases 第一步:将Redis拷 ...

  6. mac系统如何在桌面新建文件(夹)

    方法一:(终端方式,推荐) 1.在电脑上找到终端 2.指定你想要保存文件的路径,然后回车.例如桌面就是: cd desktop #或是 cd /Users/username/Desktop 有人问:假 ...

  7. js 碰撞 + 重力 运动

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. Varish 缓存

    varish 缓存 2013年06月17日,Varnish Cache 3.0.4 发布,为目前最新版本. varish是以内存作为共享容器的:内存的大小决定了它的缓存容量.相对于主要以硬盘为存储的s ...

  9. Netty入门(1) - 简介

    什么是Netty? Netty 是一个利用 Java 的高级网络的能力,隐藏其背后的复杂性而提供一个易于使用的 API 的客户端/服务器框架. Tomcat和Netty有什么区别? Netty和Tom ...

  10. 虚方法virtual、抽象方法abstract、接口interface区别

    接口.抽象类.抽象方法.虚方法: 这四个名词时非常容易混淆的: 首先说一下接口 与抽象类 的异同: 相同点: 1.他们都不能实例化自己,也就是说都是用来被继承的. 2.抽象类中的抽象方法和接口方法一样 ...