博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[BZOJ3224]普通平衡树
阅读量:6708 次
发布时间:2019-06-25

本文共 4899 字,大约阅读时间需要 16 分钟。

Problem

有以下操作

  1. 插入x数
  2. 删除x数(若有多个相同的数,因只删除一个)
  3. 查询x数的排名(若有多个相同的数,因输出最小的排名)
  4. 查询排名为x的数
  5. 求x的前驱(前驱定义为小于x,且最大的数)
  6. 求x的后继(后继定义为大于x,且最小的数)

Solution

裸的Splay:

Rotate旋转操作
Splay伸展操作

Notice

注意,删除的时候不是把这个元素都删除,而是删除一个!!!

Code

#include
#include
#include
#include
#include
using namespace std;#define sqz main#define ll long long#define reg register int#define rep(i, a, b) for (reg i = a; i <= b; i++)#define per(i, a, b) for (reg i = a; i >= b; i--)#define travel(i, u) for (reg i = head[u]; i; i = edge[i].next)const int INF = 1e9, N = 100000;const double eps = 1e-6, phi = acos(-1);ll mod(ll a, ll b) {if (a >= b || a < 0) a %= b; if (a < 0) a += b; return a;}ll read(){ ll x = 0; int zf = 1; char ch; while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();if (ch == '-') zf = -1, ch = getchar(); while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); return x * zf;}void write(ll y) { if (y < 0) putchar('-'), y = -y; if (y > 9) write(y / 10); putchar(y % 10 + '0');}int point = 0, root, pre, suf, ans;struct node{ int val[N + 5], count[N + 5], num[N + 5], son[2][N + 5], parent[N + 5]; inline void up(int u) { count[u] = count[son[0][u]] + count[son[1][u]] + num[u]; } void Rotate(int x, int &rt) { int y = parent[x], z = parent[y]; int l = (son[1][y] == x), r = 1 - l; if (y == rt) rt = x; else if (son[0][z] == y) son[0][z] = x; else son[1][z] = x; parent[x] = z; parent[son[r][x]] = y, son[l][y] = son[r][x]; parent[y] = x, son[r][x] = y; up(y); up(x); } void Splay(int x, int &rt) { while (x != rt) { int y = parent[x], z = parent[y]; if (y != rt) { if ((son[0][z] == y) ^ (son[0][y] == x)) Rotate(x, rt); else Rotate(y, rt); } Rotate(x, rt); } } void Insert(int &u, int x, int last) { if (u == 0) { u = ++point; val[u] = x, parent[u] = last, num[u] = count[u] = 1; Splay(u, root); } else { if (x > val[u]) Insert(son[1][u], x, u); else if (x < val[u]) Insert(son[0][u], x, u); else if (x == val[u]) num[u]++, count[u]++, Splay(u, root); } } void Delete(int x) { Splay(x, root); if (num[x] > 1) { num[x]--, count[x]--; return; } if (son[0][x] * son[1][x] == 0) root = son[0][x] + son[1][x]; else { int t = son[1][x]; while (son[0][t] != 0) t = son[0][t]; Splay(t, root); son[0][t] = son[0][x], parent[son[0][x]] = t; up(t); } parent[root] = 0; } void Find_pre(int u, int x) { if (u == 0) return; if (x > val[u]) { pre = u; Find_pre(son[1][u], x); ans += count[son[0][u]] + num[u]; } else Find_pre(son[0][u], x); } void Find_suf(int u,int x) { if (u == 0) return; if (x < val[u]) { suf = u; Find_suf(son[0][u], x); } else Find_suf(son[1][u], x); } int Find_num(int u, int x) { if (x <= count[son[0][u]]) return Find_num(son[0][u], x); if (x > count[son[0][u]] + num[u]) return Find_num(son[1][u], x - count[son[0][u]] - num[u]); return val[u]; } int Find_rank(int x) { ans = 0; Find_pre(root, x); return ans + 1; } int Find_id(int u, int x) { if (x == val[u]) return u; if (x > val[u]) return Find_id(son[1][u], x); if (x < val[u]) return Find_id(son[0][u], x); }}splay_tree;int sqz(){ int n = read(); root = 0; rep(i, 1, n) { int op = read(), t = read(); switch (op) { case 1: { splay_tree.Insert(root, t, 0); break; } case 2: { int x = splay_tree.Find_id(root, t); splay_tree.Delete(x); break; } case 3: { printf("%d\n", splay_tree.Find_rank(t)); break; } case 4: { printf("%d\n", splay_tree.Find_num(root, t)); break; } case 5: { splay_tree.Find_pre(root, t); printf("%d\n", splay_tree.val[pre]); break; } case 6: { splay_tree.Find_suf(root, t); printf("%d\n", splay_tree.val[suf]); break; } } } return 0;}

转载于:https://www.cnblogs.com/WizardCowboy/p/7612668.html

你可能感兴趣的文章
简单的 jQuery 浮动层随窗口滚动滑动插件实例
查看>>
我的友情链接
查看>>
Cocos2d-x3.2 Loading场景的设计
查看>>
Cocos2d-x3.2 多点触控
查看>>
企业Exchange邮件服务器搭建实例
查看>>
linux下 htop 工具简介
查看>>
Ubuntu 中文输入法安装
查看>>
服务交付经理的职责
查看>>
php-fpm监控监本
查看>>
xcode 弹出“could not change executable permission...
查看>>
Google Java编程风格指南中文版
查看>>
阿里云Linux一键安装LNMP环境使用
查看>>
EF数据库迁移
查看>>
ifconfig、ip命令详解、route路由配置、DNS配置
查看>>
redis持久化配置
查看>>
asp.net底层公共方法
查看>>
java 字符串连接
查看>>
数组的二分查找法
查看>>
Android之SurfaceView简单分析
查看>>
js-数值保留2位小数?
查看>>