飞旋treap
虽然叫做非旋treap但是飞旋treap很带感所以就用这个名字了(SB)
这个东西是真的好写......
主要的两个函数只有两个,rotate和splay,split和merge。
merge就是大家都熟悉的左偏树合并,线段树合并......注意不能swap(x, y)
split分为splitV和splitS,按权值分,按大小分。
inline void splitS(int o, int k, int &x, int &y) {
if(!o) {
x = y = ;
return;
}
//pushdown(o);
if(k <= siz[ls[o]]) {
y = o;
splitS(ls[y], k, x, ls[y]);
}
else {
x = o;
splitS(rs[x], k - siz[ls[o]] - , rs[x], y);
}
pushup(o);
return;
}
splitS
inline void splitV(int o, int k, int &x, int &y) {
if(!o) {
x = y = ;
return;
}
pushdown(o);
if(val[o] <= k) {
x = o;
splitV(rs[x], k, rs[x], y);
}
else {
y = o;
splitV(ls[y], k, x, ls[y]);
}
pushup(o);
return;
}
splitV
inline int merge(int x, int y) {
if(!x || !y) {
return x | y;
}
if(rd[x] >= rd[y]) {
pushdown(x);
rs[x] = merge(rs[x], y);
pushup(x);
return x;
}
else {
pushdown(y);
ls[y] = merge(x, ls[y]);
pushup(y);
return y;
}
}
merge
这个东西写着一般不去重。
接下来放例题。
#include <cstdio>
#include <algorithm>
#include <climits>
#include <cstdlib>
#include <ctime> typedef long long LL;
const int N = , INF = 0x3f3f3f3f; int ls[N], rs[N], val[N], rd[N], siz[N], tot, root; inline void pushup(int o) {
siz[o] = siz[ls[o]] + siz[rs[o]] + ;
return;
} inline void pushdown(int o) {
return;
} inline void splitV(int o, int k, int &x, int &y) {
if(!o) {
x = y = ;
return;
}
pushdown(o);
if(val[o] <= k) {
x = o;
splitV(rs[x], k, rs[x], y);
}
else {
y = o;
splitV(ls[y], k, x, ls[y]);
}
pushup(o);
return;
} inline int merge(int x, int y) {
if(!x || !y) {
return x | y;
}
if(rd[x] >= rd[y]) {
pushdown(x);
rs[x] = merge(rs[x], y);
pushup(x);
return x;
}
else {
pushdown(y);
ls[y] = merge(x, ls[y]);
pushup(y);
return y;
}
} inline int np(int k) {
int o = ++tot;
siz[o] = ;
rd[o] = (((LL)rand() << ) + rand()) % LONG_MAX;
val[o] = k;
return o;
} inline int getLP(int x) {
while(ls[x]) {
x = ls[x];
}
return x;
} inline int getRP(int x) {
while(rs[x]) {
x = rs[x];
}
return x;
} inline int cal(int l, int r, int k) {
if(l == -INF && r == INF) {
return k;
}
return std::min(k - l, r - k);
} inline void out(int x) {
if(ls[x]) {
out(ls[x]);
}
printf("%d ", val[x]);
if(rs[x]) {
out(rs[x]);
}
return;
} int main() {
srand(time());
int n;
scanf("%d", &n);
int x = np(-INF), y = np(INF);
root = merge(x, y);
LL ans = ;
for(int i = ; i <= n; i++) {
int k;
scanf("%d", &k);
splitV(root, k, x, y);
//printf("X : "); out(x); puts("");
//printf("Y : "); out(y); puts("");
int a = getRP(x), b = getLP(y);
ans += cal(val[a], val[b], k);
root = merge(merge(x, np(k)), y);
//out(root); puts("");
}
printf("%lld\n", ans);
return ;
}
洛谷P2234 营业额统计
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <climits> typedef long long LL;
const int N = , INF = 0x3f3f3f3f; int ls[N], rs[N], siz[N], val[N], rd[N], tot, root; inline void pushup(int x) {
siz[x] = siz[ls[x]] + siz[rs[x]] + ;
return;
} inline int merge(int x, int y) {
if(!x || !y) {
return x | y;
}
if(rd[x] >= rd[y]) {
//pushdown(x);
rs[x] = merge(rs[x], y);
pushup(x);
return x;
}
else {
//pushdown(y);
ls[y] = merge(x, ls[y]);
pushup(y);
return y;
}
} inline void splitV(int o, int k, int &x, int &y) {
if(!o) {
x = y = ;
return;
}
//pushdown(o);
//printf("o = %d \n", o);
if(val[o] <= k) {
x = o;
splitV(rs[x], k, rs[x], y);
}
else {
y = o;
splitV(ls[y], k, x, ls[y]);
}
pushup(o);
return;
} inline void splitS(int o, int k, int &x, int &y) {
if(!o) {
x = y = ;
return;
}
//pushdown(o);
if(k <= siz[ls[o]]) {
y = o;
splitS(ls[y], k, x, ls[y]);
}
else {
x = o;
splitS(rs[x], k - siz[ls[o]] - , rs[x], y);
}
pushup(o);
return;
} inline int np(int k) {
int o = ++tot;
siz[o] = ;
val[o] = k;
rd[o] = (((LL)rand() << ) + rand()) % LONG_MAX;
return o;
} inline void insert(int k) {
int x, y;
splitV(root, k, x, y);
root = merge(merge(x, np(k)), y);
return;
} inline int getLP(int x) {
while(ls[x]) {
x = ls[x];
}
return x;
} inline int getRP(int x) {
while(rs[x]) {
x = rs[x];
}
return x;
} inline int getVbyR(int k) {
int x, y;
splitS(root, k, x, y);
int t = val[getLP(y)];
root = merge(x, y);
return t;
} inline int getRbyV(int k) {
int x, y;
splitV(root, k - , x, y);
int t = siz[x];
root = merge(x, y);
return t;
} inline int getPre(int k) {
int x, y;
splitV(root, k - , x, y);
int t = val[getRP(x)];
root = merge(x, y);
return t;
} inline int getNex(int k) {
int x, y;
splitV(root, k, x, y);
int t = val[getLP(y)];
root = merge(x, y);
return t;
} inline void del(int k) {
int x, y, z;
splitV(root, k - , x, y);
splitS(y, , z, y);
root = merge(x, y);
return;
} int main() {
srand(time());
int n;
scanf("%d", &n);
root = merge(np(-INF), np(INF)); for(int i = , f, x; i <= n; i++) {
scanf("%d%d", &f, &x);
if(f == ) insert(x);
else if(f == ) del(x);
else if(f == ) printf("%d\n", getRbyV(x));
else if(f == ) printf("%d\n", getVbyR(x));
else if(f == ) printf("%d\n", getPre(x));
else if(f == ) printf("%d\n", getNex(x));
} return ;
}
洛谷P3369 普通平衡树
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <climits> typedef long long LL;
const int N = ; int ls[N], rs[N], val[N], rd[N], siz[N], tot, root;
bool rev[N]; inline void pushup(int x) {
siz[x] = siz[ls[x]] + siz[rs[x]] + ;
return;
} inline void pushdown(int x) {
if(rev[x]) {
std::swap(ls[x], rs[x]);
if(ls[x]) {
rev[ls[x]] ^= ;
}
if(rs[x]) {
rev[rs[x]] ^= ;
}
rev[x] = ;
}
return;
} inline int merge(int x, int y) {
if(!x || !y) {
return x | y;
}
if(rd[x] >= rd[y]) {
pushdown(x);
rs[x] = merge(rs[x], y);
pushup(x);
return x;
}
else {
pushdown(y);
ls[y] = merge(x, ls[y]);
pushup(y);
return y;
}
} inline void splitS(int o, int k, int &x, int &y) {
if(!o) {
x = y = ;
return;
}
pushdown(o);
if(k <= siz[ls[o]]) {
y = o;
splitS(ls[y], k, x, ls[y]);
}
else {
x = o;
splitS(rs[x], k - siz[ls[o]] - , rs[x], y);
}
pushup(o);
return;
} inline int np(int k) {
int o = ++tot;
siz[o] = ;
val[o] = k;
rd[o] = (((LL)rand() << ) + rand()) % LONG_MAX;
return o;
} inline void reverse(int l, int r) {
int x, y, z;
splitS(root, l, x, y);
splitS(y, r - l + , y, z);
rev[y] ^= ;
root = merge(merge(x, y), z);
return;
} inline void insert(int p, int k) {
int x, y;
splitS(root, p + , x, y);
root = merge(merge(x, np(k)), y);
return;
} void out(int x) {
pushdown(x);
if(ls[x]) out(ls[x]);
if(val[x]) printf("%d ", val[x]);
if(rs[x]) out(rs[x]);
return;
} int main() {
int n, m;
scanf("%d%d", &n, &m);
root = merge(np(), np());
for(int i = ; i <= n; i++) {
insert(i - , i);
}
for(int i = , x, y; i <= m; i++) {
scanf("%d%d", &x, &y);
reverse(x, y);
}
out(root);
return ;
}
洛谷P3391 文艺平衡树
注意不要把split里的o写成x.....
飞旋treap的更多相关文章
- fhq treap最终模板
新学习了fhq treap,厉害了 先贴个神犇的版, from memphis /* Treap[Merge,Split] by Memphis */ #include<cstdio> # ...
- BZOJ 1691: [Usaco2007 Dec]挑剔的美食家 [treap 贪心]
1691: [Usaco2007 Dec]挑剔的美食家 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 786 Solved: 391[Submit][S ...
- BZOJ 1862: [Zjoi2006]GameZ游戏排名系统 [treap hash]
1862: [Zjoi2006]GameZ游戏排名系统 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1318 Solved: 498[Submit][ ...
- 非旋treap模板
bzoj3580 非旋转treap 在大神教导下发现split一段区间时先split右边再split左边比较好写 #include <cstdio> #include <cstdli ...
- POJ2985 The k-th Largest Group[树状数组求第k大值+并查集||treap+并查集]
The k-th Largest Group Time Limit: 2000MS Memory Limit: 131072K Total Submissions: 8807 Accepted ...
- [普通平衡树treap]【学习笔记】
3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 9046 Solved: 3840[Submit][Sta ...
- UVALive5031 Graph and Queries(Treap)
反向操作,先求出最终状态,再反向操作. 然后就是Treap 的合并,求第K大值. #include<cstdio> #include<iostream> #include< ...
- 【Treap】bzoj1588-HNOI2002营业额统计
一.题目 Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司 ...
- hdu 4585 Shaolin treap
Shaolin Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Problem ...
随机推荐
- linux下的qt串口通信
1.linux下的qt串口通信跟windows唯一的差别就是端口号的名字,windows下面是COM,而linux是ttyUSB0的路径 2.一般情况下linux插上USB转串口线就可以在/dev/目 ...
- c/c++ 多线程 mutex的理解
多线程 mutex的理解 mutex,我的理解是每个mutex对象都是一个带锁头的门,这个门有两个状态,门开着和门关着,感觉像是废话... 当想查看门的里东西,或者把东西放进门里,或者从门里拿出东西前 ...
- 重装助手教你如何在Windows 10中更改您的帐户名称
当您设置新的Win10免费下载 PC时,您选择用户名的部分可能会让您措手不及.如果是这种情况,您可以选择弹出头部的第一件事或者您打算稍后更改的随机和临时事物.但令人惊讶的是,在Windows 10中更 ...
- HTML,CSS---问题记录
1,,登录框input和标签垂直方向对不齐,咋解决? 给input框外套一层span标签,给span标签设置宽高,让它和左边或右边的标签对齐. 不要直接给input设置宽高,这样是对不齐的 2,套没有 ...
- 构建高性能服务 Java高性能缓冲设计 vs Disruptor vs LinkedBlockingQueue
一个仅仅部署在4台服务器上的服务,每秒向Database写入数据超过100万行数据,每分钟产生超过1G的数据.而每台服务器(8核12G)上CPU占用不到100%,load不超过5.这是怎么做到呢?下面 ...
- Ambari与Kerberos 集成
Kerberos 介绍 Kerberos 是一个网络认证的框架协议,其设计的初衷便是通过密钥系统为 Client 和 Server 应用程序之间提供强大的认证服务.在使用 Kerberos 认证的集群 ...
- yum源 Python3 Django mysql安装
yum 源安装 yum源位置: yum源仓库的地址 在/etc/yum.repos.d/,并且只能读出第一层的repo文件 yum仓库的文件都是以.repo结尾的 linux软件包管理 yum工具如同 ...
- 《通过C#学Proto.Actor模型》之Persistence
Actor是有状态的,当每一步执行失败后,返回失败地方继续执行时,希望此时的状态是正确的,为了保证这一点,持久化就成了必要的环节了. Proto.Actor提供了三种方式执久化: Event Sour ...
- 多项目管理中PMO的作用
随着现代企业规模的不断扩大,多项目同时运行成为了现代企业的常态,以及企业项目化进程的不断深入,大部分企业不再仅仅只运行一个项目,而且数量之大已经超出了人们的想象,如惠普公司每年有3000个左右的项目, ...
- MaxCompute教程
MaxCompute全套攻略:https://blog.csdn.net/qq_35394891/article/details/82943894 [2019年大数据福利推荐]MaxCompute教程 ...