splay板子
1, splay的一些基本操作.
- 使用前要插入$-INF,+INF$保证每个点的前驱后继存在.
- $get$函数在$x$存在时, 调用后, 根为$x$, 否则根为$x$的前驱或后继
- const int N = 1e6+10;
- int n, tot, rt, sz;
- struct {
- int cnt,sz,fa,ch[2],v;
- } tr[N];
- void pu(int x) {
- tr[x].sz=tr[tr[x].ch[0]].sz+tr[tr[x].ch[1]].sz+tr[x].cnt;
- }
- void rot(int x) {
- int y=tr[x].fa,z=tr[y].fa;
- int f=tr[y].ch[1]==x;
- tr[z].ch[tr[z].ch[1]==y]=x,tr[x].fa=z;
- tr[y].ch[f]=tr[x].ch[f^1],tr[tr[x].ch[f^1]].fa=y;
- tr[x].ch[f^1]=y,tr[y].fa=x,pu(y);
- }
- void splay(int x, int s=0) {
- for (int y; y=tr[x].fa,y!=s; rot(x)) if (tr[y].fa!=s) {
- rot((tr[y].ch[0]==x)==(tr[tr[y].fa].ch[0]==y)?y:x);
- }
- if (!s) rt=x;
- }
- void get(int x) {
- int cur=rt;
- while (x!=tr[cur].v&&tr[cur].ch[x>tr[cur].v]) cur=tr[cur].ch[x>tr[cur].v];
- splay(cur);
- }
- void insert(int x) {
- int cur=rt,p=0;
- while (cur&&x!=tr[cur].v) p=cur,cur=tr[cur].ch[x>tr[cur].v];
- if (cur) ++tr[cur].cnt;
- else {
- cur=++tot;
- if (p) tr[p].ch[x>tr[p].v]=cur,tr[cur].fa=p;
- tr[cur].v=x,tr[cur].sz=tr[cur].cnt=1;
- }
- splay(cur);
- }
- int pre(int x) {
- get(x);
- if (tr[rt].v<=x) return rt;
- int cur=tr[rt].ch[0];
- while (tr[cur].ch[1]) cur=tr[cur].ch[1];
- return cur;
- }
- int nxt(int x) {
- get(x);
- if (tr[rt].v>=x) return rt;
- int cur=tr[rt].ch[1];
- while (tr[cur].ch[0]) cur=tr[cur].ch[0];
- return cur;
- }
- void erase(int x) {
- int s1=pre(x-1),s2=nxt(x+1);
- splay(s1),splay(s2,s1);
- int &cur=tr[s2].ch[0];
- if (tr[cur].cnt>1) --tr[cur].cnt,splay(cur);
- else cur=0;
- }
2, splay插入区间,区间翻转等操作.
这时候splay维护的是每个下标对应的权值, 下标通过第k大来查询
- 使用前要调用$build(a,0,rt,1,2);$
- const int N = 1e6+10;
- int n, rt, tot;
- int a[N];
- struct _ {
- int sz,v,ch[2],fa,rev;
- } tr[N];
- void pu(int o) {
- tr[o].sz=tr[tr[o].ch[0]].sz+tr[tr[o].ch[1]].sz+1;
- }
- void pd(int o) {
- if (tr[o].rev) {
- swap(tr[o].ch[0],tr[o].ch[1]);
- tr[tr[o].ch[0]].rev^=1;
- tr[tr[o].ch[1]].rev^=1;
- tr[o].rev=0;
- }
- }
- void rot(int x) {
- int y=tr[x].fa,z=tr[y].fa;
- int f=tr[y].ch[1]==x;
- tr[z].ch[tr[z].ch[1]==y]=x,tr[x].fa=z;
- tr[y].ch[f]=tr[x].ch[f^1],tr[tr[x].ch[f^1]].fa=y;
- tr[x].ch[f^1]=y,tr[y].fa=x,pu(y);
- }
- void splay(int x, int s=0) {
- for (int y; y=tr[x].fa,y!=s; rot(x)) if (tr[y].fa!=s) {
- rot((tr[y].ch[0]==x)==(tr[tr[y].fa].ch[0]==y)?y:x);
- }
- if (!s) rt=x;
- }
- int find(int x, int k) {
- pd(x); int s=tr[tr[x].ch[0]].sz;
- if (k==s+1) return x;
- if (k<=s) return find(tr[x].ch[0],k);
- return find(tr[x].ch[1],k-s-1);
- }
- void build(int *a, int f, int &o, int l, int r) {
- if (l>r) return;
- o = ++tot;
- tr[o].v = a[mid], tr[o].fa = f;
- build(s,o,tr[o].ch[0],l,mid-1);
- build(s,o,tr[o].ch[1],mid+1,r);
- pu(o);
- }
- void ins(int x, int n) {
- build(a,0,p,1,n);
- int s1=find(rt,x-1), s2=find(rt,x);
- splay(s1),splay(s2,s1);
- tr[s2].ch[0]=p,tr[p].fa=s2;
- pu(p),pu(s2);
- }
- void del(int x, int n) {
- int s1=find(rt,x-1), s2=find(rt,x+n);
- splay(s1),splay(s2,s1);
- tr[s2].ch[0]=0;
- pu(s1),pu(s2);
- }
- void reverse(int x, int n) {
- int s1=find(rt,x-1), s2=find(rt,x+n);
- splay(s1),splay(s2,s1);
- tr[tr[s2].ch[0]].rev^=1;
- }
splay板子的更多相关文章
- [bzoj] 1588 营业额统计 || Splay板子题
原题 给出一个n个数的数列ai ,对于第i个元素ai定义\(fi=min(|ai-aj|) (1<=j<i)\),f1=a1,求\(/sumfi\) Splay板子题. Splay讲解:h ...
- POJ - 3481 splay板子
Double Queue 默写splay板子 很多细节问题... #include<cstdio> #include<iostream> using namespace std ...
- 个人整理的数组splay板子,指针的写的太丑了就不放了。。
splay的板子.. 由于被LCT榨干了..所以昨天去学了数组版的splay,现在整理一下板子.. 以BZOJ3224和3223为例题..暂时只有这些,序列的话等有时间把维修序列给弄上来!! BZOJ ...
- bzoj3224 splay板子
开始学习新知识:splay——tree 是个板子题,学习splay可以看博客 https://blog.csdn.net/Clove_unique/article/details/50630280 # ...
- BZOJ 3224 Tyvj 1728 普通平衡树 | Splay 板子+SPlay详细讲解
下面给出Splay的实现方法(复杂度证明什么的知道是 nlogn 就可以啦) 首先对于一颗可爱的二叉查找树,是不能保证最坏nlogn的复杂度(可以想象把一个升序序列插入) (二叉查找树保证左子树元素大 ...
- BZOJ[NOI2004]郁闷的出纳员 | Splay板子题
题目: 洛谷也能评测....还有我wa了10多次的记录233 题解: 不要想得太复杂,搞一个全局变量记录一下工资的改变量Delta,这样可以等询问的时候就输出val+Delta,然后插入的时候插入x- ...
- P3369 【模板】普通平衡树(splay)
P3369 [模板]普通平衡树 就是不用treap splay板子,好好背吧TAT #include<iostream> #include<cstdio> #include&l ...
- 【题解】 [HNOI2004]宠物收养场(Splay)
懒得复制,戳我戳我 Solution: \(Splay\)板子,注意交换的地方,然后就是注意不要越界node[x],应该是\(node[now]\),其次就是数组可以开大点 Code: //It is ...
- 【题解】 [HNOI2002]营业额统计 (Splay)
懒得复制,戳我戳我 Solution: \(Splay\)板子题,注意可以选择相等大小 Code: //It is coded by Ning_Mew on 4.10 #include<bits ...
随机推荐
- 最新版Intellij IDEA插件JRebel 7.0.7官方免费激活
本文转自:http://blog.csdn.net/u012283609/article/details/70213307 开场语 有时候真实比小说更加荒诞,因为虚构是在一定逻辑下进行的,而现实往往毫 ...
- java多线程----JUC集合”01之 框架
java集合的架构.主体内容包括Collection集合和Map类:而Collection集合又可以划分为List(队列)和Set(集合). 1. List的实现类主要有: LinkedList, A ...
- MySQL数据库----视图
视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,可以将该结果集当做表来使用. 使用视图我们可以把查询过程中的临时 ...
- 配置mysql主从数据库
来源地址:https://www.cnblogs.com/alvin_xp/p/4162249.html Mysql主从配置,实现读写分离 大型网站为了软解大量的并发访问,除了在网站实现分布式负载均衡 ...
- shell分析http日志
http状态码1字头----信息,服务器收到请求,需要请求者继续执行操作2字头----成功,操作被成功接收并处理3字头----重定向,需要进一步的操作以完成请求4字头----客户端错误,请求包含语法错 ...
- 02:Django进阶篇
目录:Django其他篇 01:Django基础篇 02:Django进阶篇 03:Django数据库操作--->Model 04: Form 验证用户数据 & 生成html 05:Mo ...
- 20145310《网络对抗技术》Exp6 信息搜集技术
实验内容 本次实验的目标是掌握信息搜集的最基础技能.具体有 (1)各种搜索技巧的应用 (2)DNS IP注册信息的查询 (3)基本的扫描技术:主机发现.端口扫描.OS及服务版本探测.具体服务的查点 ( ...
- Android项目开发二
微博客户端开发 本周学习计划 学习布局控件和UI设计相关知识. 微博验证,学习OAuth相关知识. 看懂微博客户端开发部分代码. 把借鉴代码导入到Android Studio中并运行成功. 实际完成情 ...
- 关于STM32外接4—16MHz晶振主频处理方法
由于STM32F10x库官方采用的是默认的外接8MHz晶振,因此造成很多用户也采用了8MHz的晶振,但是,8MHz的晶振不是必须的,其他频点的晶振也是可行的,只需要在库中做相应的修改就行. 在论 ...
- 联想预装Win10/Win8换Win7 教程 以及svn使用教程
1.换系统教程 http://ideapad.it168.com/thread-4869510-1-1.html http://jingyan.baidu.com/article/08b6a591c8 ...