飞旋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 中使用 firewalld
firewalld 是一种动态防火墙管理解决方案.Centos 7 默认使用 firewalld.firewalld 是对 iptables 的一个封装,可以让你更容易地管理 iptables 规则. ...
- WPF开源项目
WPF有很多优秀的开源项目,我以为大家都知道,结果,问了很多人,其实他们不知道.唉,太可惜了! 先介绍两个比较牛逼的界面库 1.MaterialDesignInXamlToolkit Android风 ...
- Python简介之探观止矣
Python是一门什么样的编程语言编程语言主要分为编译型和解释型,静态语言和动态语言,强类型和弱类型,混合语言等.编译型语言:通过编译器把源代码编译(compile)成机器语言,在经过链接(linke ...
- c/c++ 网络编程 UDP 用if_nameindex和ioctl取得主机网络信息
网络编程 UDP 用if_nameindex和ioctl取得主机网络信息 getifaddrs函数取得的东西太多了,如果只想取得网卡名字和网卡编号可以用下面的2个函数. 1,if_nameindex ...
- Swift UIFont
设置字体 titleLabel.font = UIFont.systemFont(ofSize: 17.0, weight: .heavy)
- SQLServer之添加聚集索引
聚集索引添加规则 聚集索引按下列方式实现 PRIMARY KEY 和 UNIQUE 约束 在创建 PRIMARY KEY 约束时,如果不存在该表的聚集索引且未指定唯一非聚集索引,则将自动对一列或多列创 ...
- 英语口语练习系列-C17-Love story
词汇学习 break [breɪk] v. 打破 broke (过去式) The glass broke. 玻璃杯碎了. My watch broke. 我的表坏了. break the law 违法 ...
- 【Python实战】使用Python连接Teradata数据库???未完成
1.安装Python 方法详见:[Python 05]Python开发环境搭建 2.安装Teradata客户端ODBC驱动 安装包地址:TTU下载地址 (1)安装TeraGSS和tdicu(ODBC依 ...
- 【Python 08】汇率兑换2.0-1(字符串索引)
1.案例描述 设计一个汇率换算程序,其功能是将人民币转换为美元,或者美元转换为人民币. 增加功能:根据输入判断是人民币还是美元,进行相应的转换计算. 2.案例分析 3.字符串 两个双引号或单引号括起 ...
- iOS开发基础篇-手写控件
一.手写控件的步骤 1)使用相应的控件类创建控件对象: 2)设置该控件的各种属性: 3)添加空间到视图中: 4)如果是 UIButton 等控件,还需考虑控件的单击事件等: 二.添加 UIButton ...