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板子的更多相关文章

  1. [bzoj] 1588 营业额统计 || Splay板子题

    原题 给出一个n个数的数列ai ,对于第i个元素ai定义\(fi=min(|ai-aj|) (1<=j<i)\),f1=a1,求\(/sumfi\) Splay板子题. Splay讲解:h ...

  2. POJ - 3481 splay板子

    Double Queue 默写splay板子 很多细节问题... #include<cstdio> #include<iostream> using namespace std ...

  3. 个人整理的数组splay板子,指针的写的太丑了就不放了。。

    splay的板子.. 由于被LCT榨干了..所以昨天去学了数组版的splay,现在整理一下板子.. 以BZOJ3224和3223为例题..暂时只有这些,序列的话等有时间把维修序列给弄上来!! BZOJ ...

  4. bzoj3224 splay板子

    开始学习新知识:splay——tree 是个板子题,学习splay可以看博客 https://blog.csdn.net/Clove_unique/article/details/50630280 # ...

  5. BZOJ 3224 Tyvj 1728 普通平衡树 | Splay 板子+SPlay详细讲解

    下面给出Splay的实现方法(复杂度证明什么的知道是 nlogn 就可以啦) 首先对于一颗可爱的二叉查找树,是不能保证最坏nlogn的复杂度(可以想象把一个升序序列插入) (二叉查找树保证左子树元素大 ...

  6. BZOJ[NOI2004]郁闷的出纳员 | Splay板子题

    题目: 洛谷也能评测....还有我wa了10多次的记录233 题解: 不要想得太复杂,搞一个全局变量记录一下工资的改变量Delta,这样可以等询问的时候就输出val+Delta,然后插入的时候插入x- ...

  7. P3369 【模板】普通平衡树(splay)

    P3369 [模板]普通平衡树 就是不用treap splay板子,好好背吧TAT #include<iostream> #include<cstdio> #include&l ...

  8. 【题解】 [HNOI2004]宠物收养场(Splay)

    懒得复制,戳我戳我 Solution: \(Splay\)板子,注意交换的地方,然后就是注意不要越界node[x],应该是\(node[now]\),其次就是数组可以开大点 Code: //It is ...

  9. 【题解】 [HNOI2002]营业额统计 (Splay)

    懒得复制,戳我戳我 Solution: \(Splay\)板子题,注意可以选择相等大小 Code: //It is coded by Ning_Mew on 4.10 #include<bits ...

随机推荐

  1. IOS中position:fixed吸底时的滑动出现抖动的解决方案

    H5方法: //吸顶头部 .header{ width:100%; height:50px; position:fixed; top:0px; } //main滑动区域 .main{ width:10 ...

  2. pm2 观察报错时 pm2 start app.js --watch

    pm2 start app.js --watch[PM2][ERROR] Script already launched, add -f option to force re-execution

  3. mysql count group by统计条数方法

    mysql count group by统计条数方法 mysql 分组之后如何统计记录条数? gourp by 之后的 count,把group by查询结果当成一个表再count一次select c ...

  4. 在wamp 2.0环境下面安装Zend Optimizer的方法

    原文链接:http://blog.sina.com.cn/s/blog_8dc13ec50101pbat.html 我是用WAMP来做PHP的服务器,进行本机测试和开发PHP项目. wamp环境是刚刚 ...

  5. hdu6446 网络赛 Tree and Permutation(树形dp求任意两点距离之和)题解

    题意:有一棵n个点的树,点之间用无向边相连.现把这棵树对应一个序列,这个序列任意两点的距离为这两点在树上的距离,显然,这样的序列有n!个,加入这是第i个序列,那么这个序列所提供的贡献值为:第一个点到其 ...

  6. POJ 2029 (二维树状数组)题解

    思路: 大力出奇迹,先用二维树状数组存,然后暴力枚举 算某个矩形区域的值的示意图如下,代码在下面慢慢找... 代码: #include<cstdio> #include<map> ...

  7. SQLSERVER 内存占用高的处理方式

    https://www.cnblogs.com/srsrd/p/6962982.html 方法一: 方法二: 使用以下语句查找出什么语句占内存最高,针对占内存高的语句进行优化SELECT SS.SUM ...

  8. Ubuntu 14.04 下解决maven访问速度慢问题

    参考: maven国内镜像(maven下载慢的解决方法) maven中央仓库访问速度太慢的解决办法 Ubuntu 14.04 下解决maven访问速度慢问题 在启动OVX的时候,由于sh脚本中需要使用 ...

  9. 解决 Ubuntu 14.04 图形界面无法正常显示 问题

    参考: ubuntu清除系统缓存的方法 apt-get(四) 每天一个linux命令(33):df 命令 Ubuntu server 12.10 /dev/sda1 disk full 解决 Ubun ...

  10. 51nod 1102 面积最大的矩形(单调栈)

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1102 题意: 思路: 做法就是求出每个长方形向左向右所能延伸的最大距离. ...