BST-splay板子 - 维护一个分裂和合并的序列
splay 均摊复杂度 \(O(\log n)\) 证明: https://www.cnblogs.com/Mr-Spade/p/9715203.html
我这个 splay 有两个哨兵节点,分别是1和n+2。其实只需要一个哨兵节点就行,但是,为了美观和对称……
560ms 6.19MB
void splay(Node* &o,int x) 把左数第 x 个元素移动到根节点。
Node* merge(Node* left,Node* right) 把left树与right树合并。
void split(Node *o,int k,Node *&left,Node *&right) 把o这棵树前k个元素分裂到left树中,剩下的分裂到right树中。
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
#define IL inline
#define ri register int
typedef long long LL;
struct Node *null;
struct Node {
Node *ch[2];
int v,sz,cnt,flip;
IL Node() {}
IL Node(int v):v(v){ch[0]=ch[1]=null;flip=0;sz=cnt=1;}
IL int cmp(int k) const {
int d = k - ch[0]->sz;
if(d == 1) return -1;
return d > 0;
}
IL void upd() { sz = cnt + ch[0]->sz + ch[1]->sz;}
IL void pushdown() {
if(flip) {
flip = 0;
swap(ch[0],ch[1]);
ch[0]->flip ^= 1;
ch[1]->flip ^= 1;
}
}
};
IL void initnull() { null = new Node(); null->sz = null->v = null->cnt = null->flip = 0;}
IL void rotate(Node *&o,int d) {
Node* k = o->ch[d^1]; o->ch[d^1] = k->ch[d]; k->ch[d] = o;
o->upd(); k->upd(); o = k;
}
void splay(Node* &o,int k) {
o->pushdown();
int d = o->cmp(k);
if(d == 1) k -= o->ch[0]->sz + o->cnt;
if(d != -1) {
Node* p = o->ch[d];
p->pushdown();
int d2 = p->cmp(k);
int k2 = (d2 == 0 ? k : k - p->ch[0]->sz - p->cnt);
if(d2 != -1) {
splay(p->ch[d2],k2);
if(d == d2) rotate(o,d^1); else rotate(o->ch[d],d);
}
rotate(o,d^1);
}
}
IL Node* merge(Node* left,Node* right) {
splay(left,left->sz);
left->ch[1] = right;
left->upd();
return left;
}
IL void split(Node* o,int k,Node *&left, Node *&right) {
splay(o,k);
left = o;
right = o->ch[1];
o->ch[1] = null;
left->upd();
}
const int N = 1e5 + 9;
int n,m,valcnt;
int val[N];
Node *root;
IL Node* build(int sz) {
if(!sz) return null;
Node *l = build(sz/2);
Node *o = new Node(val[++valcnt]);
o->ch[0] = l; o->ch[1] = build(sz-sz/2-1);
o->upd();
return o;
}
IL void init(int sz) {
initnull(); root = null;
for(int i=0;i<=n+2;i++) val[i] = i;
valcnt = 0;
root = build(sz);
}
vector<int> ans;
void print(Node *o) {
if(o == null) return;
o->pushdown();
print(o->ch[0]);
ans.push_back(o->v);
print(o->ch[1]);
}
int main() {
scanf("%d%d",&n,&m);
init(n+2);
// print(root);
// printf("anscnt=%d\n",anscnt);
// for(int i=1;i<anscnt-1;i++) printf("%d ",ans[i]-1);
// printf("\n");
while(m--) {
int a,b; scanf("%d%d",&a,&b);
Node *left,*mid,*right,*o;
split(root,a,left,o);
split(o,b-a+1,mid,right);
//if(root == null) printf("opsplit:root == null\n");
mid->flip ^= 1;
root = merge(merge(left,mid),right);
//if(root == null) printf("opmerge:root == null\n");
}
ans.clear();
print(root);
//if(root == null) printf("end:root == null\n");
//printf("anscnt=%d\n",anscnt);
for(int i=1;i<ans.size()-1;i++) printf("%d ",ans[i]-1);
return 0;
}
BST-splay板子 - 维护一个分裂和合并的序列的更多相关文章
- 模板——伸展树 splay 实现快速分裂合并的序列
伸展操作:将treap中特定的结点旋转到根 //将序列中从左数第k个元素伸展到根,注意结点键值保存的是原序列id void splay(Node* &o, int k) { ] == NULL ...
- [BZOJ4552][TJOI2016&&HEOI2016]排序(二分答案+线段树/线段树分裂与合并)
解法一:二分答案+线段树 首先我们知道,对于一个01序列排序,用线段树维护的话可以做到单次排序复杂度仅为log级别. 这道题只有一个询问,所以离线没有意义,而一个询问让我们很自然的想到二分答案.先二分 ...
- POJ - 3481 splay板子
Double Queue 默写splay板子 很多细节问题... #include<cstdio> #include<iostream> using namespace std ...
- 区间树Splay——[NOI2005]维护数列
无指针Splay超详细讲解 区间树这玩意真TM玄学. 学这东西你必须要拥有的 1.通过[模板]文艺平衡树(Splay),[模板]普通平衡树,GSS3 - Can you answer these qu ...
- BST,Splay平衡树学习笔记
BST,Splay平衡树学习笔记 1.二叉查找树BST BST是一种二叉树形结构,其特点就在于:每一个非叶子结点的值都大于他的左子树中的任意一个值,并都小于他的右子树中的任意一个值. 2.BST的用处 ...
- Java中使用IO流实现大文件的分裂与合并
文件分割应该算一个比较实用的功能,举例子说明吧比如说:你有一个3G的文件要从一台电脑Copy到另一台电脑, 但是你的存储设备(比如SD卡)只有1G ,这个时候就可以把这个文件切割成3个1G的文件 ,分 ...
- [bzoj] 1588 营业额统计 || Splay板子题
原题 给出一个n个数的数列ai ,对于第i个元素ai定义\(fi=min(|ai-aj|) (1<=j<i)\),f1=a1,求\(/sumfi\) Splay板子题. Splay讲解:h ...
- BZOJ 3224 Tyvj 1728 普通平衡树 | Splay 板子+SPlay详细讲解
下面给出Splay的实现方法(复杂度证明什么的知道是 nlogn 就可以啦) 首先对于一颗可爱的二叉查找树,是不能保证最坏nlogn的复杂度(可以想象把一个升序序列插入) (二叉查找树保证左子树元素大 ...
- BZOJ1492:[NOI2007]货币兑换 (CDQ分治+斜率优化DP | splay动态维护凸包)
BZOJ1492:[NOI2007]货币兑换 题目传送门 [问题描述] 小Y最近在一家金券交易所工作.该金券交易所只发行交易两种金券:A纪念券(以下简称A券)和B纪念券(以下简称B券).每个持有金券的 ...
- HDU 5945 维护一个单调队列 dp
Fxx and game Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others)Tot ...
随机推荐
- 实践探讨Python如何进行异常处理与日志记录
本文分享自华为云社区<Python异常处理与日志记录构建稳健可靠的应用>,作者:柠檬味拥抱. 异常处理和日志记录是编写可靠且易于维护的软件应用程序中至关重要的组成部分.Python提供了强 ...
- NoSQL 数据库管理工具,搭载强大支持:Redis、Memcached、SSDB、LevelDB、RocksDB,为您的数据存储提供无与伦比的灵活性与性能!
NoSQL 数据库管理工具,搭载强大支持:Redis.Memcached.SSDB.LevelDB.RocksDB,为您的数据存储提供无与伦比的灵活性与性能! [官网地址]:http://www.re ...
- 开发日记:中控PUSH协议
using System; using System.IO; using System.Net; using System.Text.RegularExpressions; namespace Con ...
- 2024 CKA考试
一.考试形式 第一次考试可能有点紧张,训练时1小时不到搞定,考试用了1个半小时,记得考试前多练几次题目,就算紧张也可以在120分钟里考完,可以记住关键词去kubernetes.io中查找 考试模式:线 ...
- LLM应用实战:当KBQA集成LLM(二)
1. 背景 又两周过去了,本qiang~依然奋斗在上周提到的项目KBQA集成LLM,感兴趣的可通过传送门查阅先前的文章<LLM应用实战:当KBQA集成LLM>. 本次又有什么更新呢?主要是 ...
- LVGL scroll超出父界面不隐藏
问题 超出父界面不隐藏问题,即时使用了lv_obj_set_style_clip_corner()函数,也不起作用,如下图所示: 即使使用lv_obj_set_style_clip_corner(vi ...
- 云原生最佳实践系列 6:MSE 云原生网关使用 JWT 进行认证鉴权
01 方案概述 MSE 网关可以为后端服务提供转发路由能力,在此基础上,一些敏感的后端服务需要特定认证授权的用户才能够访问.MSE 云原生网关致力于提供给云上用户体系化的安全解决方案,其中 JWT 认 ...
- B/S 结构系统的 缓存机制(Cookie) 以及基于 cookie 机制实现 oa 十天免登录的功能
B/S 结构系统的 缓存机制(Cookie) 以及基于 cookie 机制实现 oa 十天免登录的功能 @ 目录 B/S 结构系统的 缓存机制(Cookie) 以及基于 cookie 机制实现 oa ...
- 圈子社交系统--在线了解前后端,APP小程序H5,三端源码交付-多重玩法,新奇有趣。
圈子论坛社区系统,含完整的后台PHP系统.功能:小程序授权登陆,H5和APP,手机号登陆,发帖,建圈子.发活动.圈主可置顶推荐帖子,关注.点赞.评论.交流等.可作为圈子贴吧等自媒体. 一款全开源支持免 ...
- TCP/IP协议栈及网络基础
TCP/IP协议栈及网络基础 目录 TCP/IP协议栈及网络基础 1. TCP/IP协议栈及网络基础 1.1 OSI网络模型 1.2 TCP/IP网络模型 1.2.1 物理层 1.2.2 数据链路层 ...