红黑树 ------ luogu P3369 【模板】普通平衡树(Treap/SBT)
二次联通门 : luogu P3369 【模板】普通平衡树(Treap/SBT)
近几天闲来无事。。。就把各种平衡树都写了一下。。。
下面是红黑树(Red Black Tree)
喜闻乐见拿到了luogu,COGS的rank1
QAQ rank1没啦!!!被树状数组艹啦!!!
10.11 Updata 压了压行233333
#include <cstdio>
#include <iostream>
#define Max 100001
#define Red true
#define Black false
const int BUF = ; char Buf[BUF], *buf = Buf;
#define rg register
#define Inline __attri\
bute__( ( optimize( "-O2" ) ) )
Inline void read (int &n)
{
bool temp = false;
for (n = ; !isdigit (*buf); ++ buf) if (*buf == '-') temp = true;
for (; isdigit (*buf); n = n * + *buf - '', ++ buf);
if (temp) n = -n;
}
struct RD
{
int v, _s, _w; bool _c; RD *f, *c[];
Inline void Fill (const int &_v, const bool &__c, const int &z, rg RD *n)
{ v = _v, _c = __c, _s = _w = z, f = c[] = c[] = n; }
Inline void Up () { _s = c[]->_s + c[]->_s + _w; }
Inline void dn ()
{ for (RD *n = this; n->_s; n = n->f) -- n->_s; }
Inline int Get_Pos (const int &n) { return this->v == n ? - : n > v; }
};
class Red_Black_Tree
{
private : int _t; RD *Rt, *null, poor[Max], *Tail, *reuse[Max];
private : Inline RD *New (const int &v)
{
rg RD *n = null;
if (!_t) n = Tail ++; else n = reuse[-- _t];
n->Fill (v, Red, , null);
return n;
} Inline void R (RD *&n, const bool &_p)
{
rg RD *C = n->c[_p ^ ];
n->c[_p ^ ] = C->c[_p];
if (C->c[_p]->_s) C->c[_p]->f = n;
C->f = n->f; if (!n->f->_s) Rt = C;
else n->f->c[n->f->c[] != n] = C;
C->c[_p] = n; n->f = C; C->_s = n->_s; n->Up ();
} Inline void If (rg RD *&n)
{
for (; n->f->_c; )
{
RD *_F = n->f, *_g = _F->f;
bool _p = _F == _g->c[]; RD *_u = _g->c[_p];
if (_u->_c) _F->_c = _u->_c = Black, _g->_c = Red, n = _g;
else if (n == _F->c[_p]) R (n = _F, _p ^ );
else _g->_c = Red, _F->_c = Black, R (_g, _p);
}
Rt->_c = Black;
} Inline RD *Find (RD *n, int v)
{
for (; n->_s && n->v != v; n = n->c[n->v < v]);
return n;
} Inline void Df (rg RD *&n)
{
for (; n != Rt && n->_c == Black; )
{
rg bool _p = n == n->f->c[];
RD *_F = n->f, *_u = _F->c[_p];
if (_u->_c == Red)
_u->_c = Black, _F->_c = Red, R (n->f, _p ^ ), _u = _F->c[_p];
else if (_u->c[]->_c == Black && _u->c[]->_c == Black)
_u->_c = Red, n = _F;
else
{
if (_u->c[_p]->_c == Black)
_u->c[_p ^ ]->_c = Black, _u->_c = Red, R (_u, _p), _u = _F->c[_p];
_u->_c = _F->_c, _u->c[_p]->_c = _F->_c = Black, R (_F, _p ^ );
break;
}
}
n->_c = Black;
} public : Red_Black_Tree ()
{
_t = , Tail = &poor[_t];
null = Tail ++, null->Fill (, Black, , NULL), Rt = null;
} Inline void Insert (const int &v)
{
rg RD *n = Rt, *_F = null;
rg int _p;
for (; n->_s; n = n->c[_p])
{
++ n->_s, _F = n, _p = n->Get_Pos (v);
if (_p == -) { ++ n->_w; return ; }
}
n = New (v);
if (_F->_s) _F->c[v > _F->v] = n; else Rt = n;
n->f = _F; If (n);
} Inline void Delete (const int &v)
{
rg RD *_r = Find (Rt, v);
if (!_r->_s) return ;
if (_r->_w > ) { -- _r->_w, _r->dn (); return ; }
rg RD *_F = _r, *n = null;
if (_r->c[]->_s && _r->c[]->_s)
for (_F = _r->c[]; _F->c[]->_s; _F = _F->c[]);
n = _F->c[!_F->c[]->_s], n->f = _F->f;
if (!_F->f->_s) Rt = n;
else _F->f->c[_F->f->c[] == _F] = n;
if (_r != _F) _r->v = _F->v, _r->_w = _F->_w;
_F->f->dn ();
for (RD *p = _F->f; _F->_w > && p->_s && p != _r; p->_s -= _F->_w - , p = p->f);
if (_F->_c == Black) Df (n);
reuse[_t ++] = _F;
} Inline int Get_kth_number (rg int k)
{
rg int _r; rg RD *n = Rt;
for (; n->_s; )
{
_r = n->c[]->_s;
if (k <= _r) n = n->c[];
else if (_r + <= k && k <= _r + n->_w) break;
else k -= _r + n->_w, n = n->c[];
}
return n->v;
} Inline int Get_rank (const int &v)
{
rg int _r, cur = ; rg RD *n = Rt;
for (; n->_s; )
{
_r = n->c[]->_s;
if (n->v == v) break;
else if (n->v > v) n = n->c[];
else cur += _r + n->_w, n = n->c[];
}
return cur + _r + ;
} Inline int Find_Suffix (const int &v)
{
rg int _r = ;
for (RD *n = Rt; n->_s; )
if (n->v > v) _r = n->v, n = n->c[];
else n = n->c[];
return _r; } Inline int Find_Prefix (const int &v)
{
rg int _r = ;
for (RD *n = Rt; n->_s; )
if (n->v < v) _r = n->v, n = n->c[];
else n = n->c[];
return _r;
}
};
Red_Black_Tree Rbt;
void write_ (int n)
{ if (n > ) write_ (n / ); putchar (n % + ''); }
inline void write (int n)
{
if (n < ) putchar ('-'), n = -n;
write_ (n); putchar ('\n');
}
int Main ()
{
fread (buf, , BUF, stdin); int N; read (N);
for (int type, x; N --; )
{
read (type); read (x);
if (type == ) Rbt.Insert (x);
else if (type == ) Rbt.Delete (x);
else if (type == ) write (Rbt.Get_rank (x));
else if (type == ) write (Rbt.Get_kth_number (x));
else if (type == ) write (Rbt.Find_Prefix (x));
else write (Rbt.Find_Suffix (x));
}
return ;
}
int ZlycerQan = Main(); int main(int argc, char *argv[]){;}
#include <cstdio>
#include <iostream> #define Max 100001 #define Red true
#define Black false const int BUF = ;
char Buf[BUF], *buf = Buf; #define Inline __attri\
bute__( ( optimize( "-O2" ) ) )
Inline void read (int &now)
{
int temp = ;
for (now = ; !isdigit (*buf); ++ buf)
if (*buf == '-')
temp = ;
for (; isdigit (*buf); now = now * + *buf - '', ++ buf);
if (temp)
now = -now;
} struct R_D
{
int key, size, weigth;
bool color; R_D *father, *child[]; Inline void Fill (const int &__key, const bool &__color, const int &z, register R_D *now)
{
this->key = __key;
this->color = __color;
this->size = this->weigth = z; this->father = this->child[] = this->child[] = now;
} Inline void Up ()
{
this->size = this->child[]->size + this->child[]->size + this->weigth;
} Inline void Down ()
{
for (R_D *now = this; now->size; now = now->father)
now->size --;
} Inline int Get_Pos (const int &now) const
{
return this->key == now ? - : now > this->key;
}
}; class Red_Black_Tree
{ private : int Top; R_D *Root, *null;
R_D poor[Max], *Tail, *reuse[Max]; Inline R_D *New (const int &key)
{
register R_D *now = null;
if (!Top)
now = Tail ++;
else
now = reuse[-- Top];
now->Fill (key, Red, , null);
return now;
} Inline void Rotate (R_D *&now, const bool &pos)
{
register R_D *C = now->child[pos ^ ];
now->child[pos ^ ] = C->child[pos];
if (C->child[pos]->size)
C->child[pos]->father = now;
C->father = now->father;
if (!now->father->size)
Root = C;
else
now->father->child[now->father->child[] != now] = C;
C->child[pos] = now;
now->father = C;
C->size = now->size;
now->Up ();
} Inline void Insert_Fill (register R_D *&now)
{
for (; now->father->color; )
{
R_D *Father = now->father, *Grand = Father->father;
bool pos = Father == Grand->child[];
R_D *Uncle = Grand->child[pos];
if (Uncle->color)
{
Father->color = Uncle->color = Black;
Grand->color = Red;
now = Grand;
}
else if (now == Father->child[pos])
Rotate (now = Father, pos ^ );
else
{
Grand->color = Red;
Father->color = Black;
Rotate (Grand, pos);
}
}
Root->color = Black;
} Inline R_D *Find (R_D *now, int key)
{
for (; now->size && now->key != key; now = now->child[now->key < key]);
return now;
} Inline void Delete_Fill (register R_D *&now)
{
for (; now != Root && now->color == Black; )
{
register bool pos = now == now->father->child[];
R_D *Father = now->father, *Uncle = Father->child[pos];
if (Uncle->color == Red)
{
Uncle->color = Black;
Father->color = Red;
Rotate (now->father, pos ^ );
Uncle = Father->child[pos];
}
else if (Uncle->child[]->color == Black && Uncle->child[]->color == Black)
{
Uncle->color = Red;
now = Father;
}
else
{
if (Uncle->child[pos]->color == Black)
{
Uncle->child[pos ^ ]->color = Black;
Uncle->color = Red;
Rotate (Uncle, pos);
Uncle = Father->child[pos];
}
Uncle->color = Father->color;
Uncle->child[pos]->color = Father->color = Black;
Rotate (Father, pos ^ );
break;
}
}
now->color = Black;
} public : Red_Black_Tree ()
{
Top = ;
Tail = &poor[Top];
null = Tail ++;
null->Fill (, Black, , NULL);
Root = null;
} Inline void Insert (const int &key)
{
register R_D *now = Root, *Father = null;
register int pos;
for (; now->size; now = now->child[pos])
{
now->size ++;
Father = now;
pos = now->Get_Pos (key);
if (pos == -)
{
now->weigth ++;
return ;
}
}
now = New (key);
if (Father->size)
Father->child[key > Father->key] = now;
else
Root = now;
now->father = Father;
this->Insert_Fill (now);
} Inline void Delete (const int &key)
{
register R_D *res = Find (Root, key);
if (!res->size)
return ;
if (res->weigth > )
{
res->weigth --;
res->Down ();
return ;
}
register R_D *Father = res, *now = null; if (res->child[]->size && res->child[]->size)
for (Father = res->child[]; Father->child[]->size; Father = Father->child[]); now = Father->child[!Father->child[]->size];
now->father = Father->father;
if (!Father->father->size)
Root = now;
else
Father->father->child[Father->father->child[] == Father] = now; if (res != Father)
{
res->key = Father->key;
res->weigth = Father->weigth;
} Father->father->Down (); for (R_D *Fuck = Father->father; Father->weigth > && Fuck->size && Fuck != res; Fuck->size -= Father->weigth - , Fuck = Fuck->father); if (Father->color == Black)
Delete_Fill (now); reuse[Top ++] = Father;
} Inline int Get_kth_number (register int k)
{
register int res;
register R_D *now = Root; for (; now->size; )
{
res = now->child[]->size; if (k <= res)
now = now->child[];
else if (res + <= k && k <= res + now->weigth)
break;
else
{
k -= res + now->weigth;
now = now->child[];
}
}
return now->key;
} Inline int Get_rank (const int &key)
{
register int res, cur = ;
register R_D *now = Root; for (; now->size; )
{
res = now->child[]->size;
if (now->key == key)
break;
else if (now->key > key)
now = now->child[];
else
{
cur += res + now->weigth;
now = now->child[];
}
} return cur + res + ;
} Inline int Find_Suffix (const int &key)
{
register int res = ; for (R_D *now = Root; now->size; )
if (now->key > key)
{
res = now->key;
now = now->child[];
}
else
now = now->child[]; return res; } Inline int Find_Prefix (const int &key)
{
register int res = ; for (R_D *now = Root; now->size; )
if (now->key < key)
{
res = now->key;
now = now->child[];
}
else
now = now->child[];
return res;
}
}; Red_Black_Tree Rbt; void write_ (int now)
{
if (now > )
write_ (now / );
putchar (now % + '');
} inline void write (int now)
{
if (now < ) putchar ('-'), now = -now;
write_ (now);
putchar ('\n');
} int N; int Main ()
{
fread (buf, , BUF, stdin);
read (N); for (int type, x; N --; )
{
read (type);
read (x); switch (type)
{
case :
Rbt.Insert (x);
break;
case :
Rbt.Delete (x);
break;
case :
write (Rbt.Get_rank (x));
break;
case :
write (Rbt.Get_kth_number (x));
break;
case :
write (Rbt.Find_Prefix (x));
break;
case :
write (Rbt.Find_Suffix (x));
break;
}
} return ;
}
int ZlycerQan = Main();
int main(int argc, char *argv[]){;}
红黑树 ------ luogu P3369 【模板】普通平衡树(Treap/SBT)的更多相关文章
- luoguP3369[模板]普通平衡树(Treap/SBT) 题解
链接一下题目:luoguP3369[模板]普通平衡树(Treap/SBT) 平衡树解析 #include<iostream> #include<cstdlib> #includ ...
- 【模板】平衡树——Treap和Splay
二叉搜索树($BST$):一棵带权二叉树,满足左子树的权值均小于根节点的权值,右子树的权值均大于根节点的权值.且左右子树也分别是二叉搜索树.(如下) $BST$的作用:维护一个有序数列,支持插入$x$ ...
- 二叉树、平衡二叉树、红黑树、B树、B+树与B*树
转: 二叉树.平衡二叉树.红黑树.B树.B+树与B*树 一.二叉树 1️⃣二叉查找树的特点就是左子树的节点值比父亲节点小,而右子树的节点值比父亲节点大,如图: 基于二叉查找树的这种特点,在查找某个节点 ...
- 树:BST、AVL、红黑树、B树、B+树
我们这个专题介绍的动态查找树主要有: 二叉查找树(BST),平衡二叉查找树(AVL),红黑树(RBT),B~/B+树(B-tree).这四种树都具备下面几个优势: (1) 都是动态结构.在删除,插入操 ...
- Java集合详解6:TreeMap和红黑树
Java集合详解6:TreeMap和红黑树 初识TreeMap 之前的文章讲解了两种Map,分别是HashMap与LinkedHashMap,它们保证了以O(1)的时间复杂度进行增.删.改.查,从存储 ...
- 二叉查找树、平衡二叉树、红黑树、B-/B+树性能对比
转载:https://blog.csdn.net/z702143700/article/details/49079107 前言:BST.AVL.RBT.B-tree都是动态结构,查找时间基本都在O(l ...
- map,set的底层实现:红黑树[多图,手机慎入]
最近天下有一种颇不太平的感觉,各地的乱刀砍人,到处是贪官服法.京东准备上市了,阿里最近也提交申请了,猎豹也逆袭了,据说猎豹移动在国际市场上表现甚是抢眼.只有屌丝还在写着代码.花开花又谢,花谢花又开,为 ...
- [luogu P3369]【模板】普通平衡树(Treap/SBT)
[luogu P3369][模板]普通平衡树(Treap/SBT) 题目描述 您需要写一种数据结构(可参考题目标题),来维护一些数,其中需要提供以下操作: 插入x数 删除x数(若有多个相同的数,因只删 ...
- 数组splay ------ luogu P3369 【模板】普通平衡树(Treap/SBT)
二次联通门 : luogu P3369 [模板]普通平衡树(Treap/SBT) #include <cstdio> #define Max 100005 #define Inline _ ...
随机推荐
- go liteIDE 快捷键
Goland常用快捷键文件相关快捷键: CTRL+E,打开最近浏览过的文件.CTRL+SHIFT+E,打开最近更改的文件.CTRL+N,可以快速打开struct结构体.CTRL+SHIFT+N,可以快 ...
- 二分法在JavaScript中的应用实例
前言:原来一直对算法和数据结构望而却步,总觉得前端可能对这块要求不用那么高,但是随着开发经验的增长以及阅历的提升,发现算法和数据结构还是相当重要的,在一些复杂功能的研发中都可以看得到它们的身影.要想提 ...
- 论文笔记 XGBoost: A Scalable Tree Boosting System
XGBoost是boosting算法的其中一种.Boosting算法的思想是将许多弱分类器集成在一起形成一个强分类器,其更关注与降低基模型的偏差.XGBoost是一种提升树模型(Gradient bo ...
- Core Animation笔记(特殊图层)
1.shapeLayer: 渲染快速,内存占用小,不会被图层边界裁掉(可以在边界之外绘制),不会像素化(当做3D变化如缩放是不会失真) CGRect rect = self.containerView ...
- 2019.7月-前端面试总结(H5+C3+JS+ES6+Vue+浏览器)
第二次面试 HTML HTML5中的新标签,举例一下 canvas绘画,本地离线存储localStorage,sessionStorage,video和audio元素,语义化元素,表单类型(date, ...
- uc/xi
一个较为通用的定义为:嵌入式系统是对对象进行自动控制而使其具有智能化并可嵌入对象体系统中的专用计算机系统. 实时性:目前,嵌入式系统广泛应用于生产过程控制.数据采集.传输通信等场合,这些应用的共同特点 ...
- mac中git使用
配置用户名及邮箱在使用Git提交前,必须配置用户名和邮箱,这些信息会永久保存到历史记录中.git config --global user.name "xxxxxx"git con ...
- 使用Kerberos进行Hadoop认证
使用Kerberos进行Hadoop认证 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. Kerberos是一种网络身份验证协议.它旨在通过使用秘密密钥加密为客户端/服务器应用程序提 ...
- https跳http
listen 443 ssl;rewrite ^ http://$http_host$request_uri? permanent;
- ubuntu---对比工具Meld
Beyond Compare是商业软件,下载地址:http://www.scootersoftware.com/download.php.下载完直接运行或者通过dpkg安装即可. 其实Linux下文本 ...