虽然叫做非旋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的更多相关文章

  1. fhq treap最终模板

    新学习了fhq treap,厉害了 先贴个神犇的版, from memphis /* Treap[Merge,Split] by Memphis */ #include<cstdio> # ...

  2. BZOJ 1691: [Usaco2007 Dec]挑剔的美食家 [treap 贪心]

    1691: [Usaco2007 Dec]挑剔的美食家 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 786  Solved: 391[Submit][S ...

  3. BZOJ 1862: [Zjoi2006]GameZ游戏排名系统 [treap hash]

    1862: [Zjoi2006]GameZ游戏排名系统 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1318  Solved: 498[Submit][ ...

  4. 非旋treap模板

    bzoj3580 非旋转treap 在大神教导下发现split一段区间时先split右边再split左边比较好写 #include <cstdio> #include <cstdli ...

  5. POJ2985 The k-th Largest Group[树状数组求第k大值+并查集||treap+并查集]

    The k-th Largest Group Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 8807   Accepted ...

  6. [普通平衡树treap]【学习笔记】

    3224: Tyvj 1728 普通平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 9046  Solved: 3840[Submit][Sta ...

  7. UVALive5031 Graph and Queries(Treap)

    反向操作,先求出最终状态,再反向操作. 然后就是Treap 的合并,求第K大值. #include<cstdio> #include<iostream> #include< ...

  8. 【Treap】bzoj1588-HNOI2002营业额统计

    一.题目 Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司 ...

  9. hdu 4585 Shaolin treap

    Shaolin Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Problem ...

随机推荐

  1. bootstrap-treeview 在 bootstrap 4 不兼容解决办法及使用

    bootstrap-treeview 是bootstrap的一个树形插件,插件依赖: bootstrap/3.3.7 jquery/3.3.1 经过验证,它不可以在 bootstrap 高于 3.3. ...

  2. Left Jion和where区别

    首先,新建两张表A和B,然后插入6条数据到A表,3条数据到B表.语句如下: create table A( ID ,) not null, AName ) null ) create table B( ...

  3. mysql安装和配置(windowns||centos)

    windows10版本安装 1.获取mysql压缩包 https://dev.mysql.com/downloads/mysql/ 2.解压并配置文件my.ini .解压的文件路径 D:\Progra ...

  4. SpringBoot+Maven多模块项目(创建、依赖、打包可执行jar包部署测试)完整流程

    一,创建Maven多模块项目先建立外层父工程         File →new →project  选择Spring Initializr          Next下一步到以下页面 工程结构如下 ...

  5. SQLServer之创建辅助XML索引

    创建辅助XML索引 使用 CREATE INDEX (Transact-SQL)Transact-SQL DDL 语句可创建辅助 XML 索引并且可指定所需的辅助 XML 索引的类型. 创建辅助 XM ...

  6. LeetCode算法题-Longest Uncommon Subsequence I(Java实现)

    这是悦乐书的第252次更新,第265篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第119题(顺位题号是521).给定一组两个字符串,您需要找到这组两个字符串中最长的不同 ...

  7. 2星|《IT真相》:日本咨询师面对美国云服务的发展,对日本IT业哀其不争

    IT真相-打通IT与商务的通路 I 作者是日本管理咨询师,对日本的IT和金融业了解比较多.书的内容是:作者看到美国的云服务发展壮大,日本IT业没能抓住机会,对日本IT业做了一些批评,比如不思进取,不了 ...

  8. Idea+Maven创建scala项目

    1.选择Create New Project 2.如下图选择,然后下一步 3.一直Next,填写groupID,artifactid,projectName之后等待IDEA初始化. 4.IDEA完成初 ...

  9. 浅析String类

    这是对于String类的一些总结,我将会从几个方面并且结合着字符串池等相关知识进行总结 进程如下:                1.对于String类基本知识的一些总结 2.简要介绍字符串池 3.分 ...

  10. CentOS下部署Redis集群

    一.部署环境 服务器三台: 10.10.15.41(配置运行两个实例,端口:6379,6380) 10.10.15.42(配置运行两个实例,端口:6381,6382) 10.10.15.43(配置运行 ...