splay 学习笔记
来源:互联网 发布:唯品会类似淘宝客 编辑:程序博客网 时间:2024/06/05 14:43
1.维护BST
例:BZOJ 1588
splay 通过旋转保证时间复杂度
定义 u.lson.x < u.x < u.rson.x (BST定义)
旋转与splay(将点v旋转至根)
inline void lnk(int u,int f,int k) {T[u].fa = f; T[f].son[k] = u;}inline void rot(int v) { int u = T[v].fa, k = (T[u].son[0] == v) ? 0 : 1; lnk(v,T[u].fa,(T[T[u].fa].son[0] == u) ? 0 : 1); lnk(T[v].son[!k],u,k); lnk(u,v,!k);}inline void splay(int v) { for (int u;u=T[v].fa;rot(v)) if (T[u].fa) rot(((T[T[v].fa].son[0] == v) ^ (T[T[u].fa].son[0] == u)) ? v : u);}
#include <cstdio>#include <cstring>#include <algorithm>#define N 100100using namespace std;struct node {int son[2],fa,x;} T[N];inline void lnk(int u,int f,int k) {T[u].fa = f; T[f].son[k] = u;}inline void rot(int v) { int u = T[v].fa, k = (T[u].son[0] == v) ? 0 : 1; lnk(v,T[u].fa,(T[T[u].fa].son[0] == u) ? 0 : 1); lnk(T[v].son[!k],u,k); lnk(u,v,!k);}void splay(int v) { for (int u;u=T[v].fa;rot(v)) if (T[u].fa) rot(((T[T[v].fa].son[0] == v) ^ (T[T[u].fa].son[0] == u)) ? v : u);}int n,now = 1,i,x,p,q,ans,root;inline bool set(int u,int x) { while (T[u].x != x && T[u].son[T[u].x < x]) u = T[u].son[T[u].x < x]; if (T[u].x == x) {splay(root = u); return true;} else { T[T[u].son[T[u].x < x] = ++now] = (node) {0,0,u,x}; splay(root = now); return false; }}int pre(int u) {if (!u) return 0xbfffffff; while (T[u].son[1]) u = T[u].son[1]; return T[u].x;}int suc(int u) {if (!u) return 0x3fffffff; while (T[u].son[0]) u = T[u].son[0]; return T[u].x;}int main() { freopen("_in.txt","r",stdin); scanf("%d%d",&n,&x); ans = T[root = now = 1].x = x; while (--n) { scanf("%d",&x); if (set(root,x)) continue; ans += min(x-pre(T[root].son[0]),suc(T[root].son[1])-x); } printf("%d",ans);}
2.线段树+
例题:luogu3391
无论 splay 怎么旋转,中序遍历不变
理论上 splay 可以实现线段树的所有操作 (包括lazy_tag)
因此可用 splay 处理区间反转问题
#include <cstdio>#include <cstring>#include <algorithm>#define N 100100using namespace std;struct node {int son[2],fa,x,sum,lazy;} T[N];int root,now,n,m,i;inline void lnk(int u,int f,int k) {T[u].fa = f; T[f].son[k] = u;}inline void rot(int v) { int u = T[v].fa, k = T[u].son[1] == v; lnk(v,T[u].fa,T[T[u].fa].son[1] == u); lnk(T[v].son[!k],u,k); lnk(u,v,!k); T[u].sum = T[T[u].son[0]].sum + T[T[u].son[1]].sum + 1; T[v].sum = T[T[v].son[0]].sum + T[T[v].son[1]].sum + 1;}inline void splay(int v,int to) { for (int u;(u=T[v].fa) != to && u;rot(v)) if (T[u].fa != to && u) rot(((T[T[u].fa].son[1] == u) ^ (T[T[u].fa].son[1] == u)) ? v : u); if (!to) root = v;}inline void push_down(int u) { if (T[u].lazy) T[T[u].son[0]].lazy ^= 1, T[T[u].son[1]].lazy ^= 1, swap(T[u].son[0],T[u].son[1]), T[u].lazy = 0;}int build(int l=0,int r=n+1) { if (l > r) return 0; int mid = (l+r) >> 1, ls = build(l,mid-1), u = ++now, rs = build(mid+1,r); T[ls].fa = T[rs].fa = u; T[u].sum = T[T[u].son[0] = ls].sum + T[T[u].son[1] = rs].sum + 1; T[u].x = mid; return u;}int kth(int u,int k) { push_down(u); if (k == T[T[u].son[0]].sum + 1) return u; if (k <= T[T[u].son[0]].sum) return kth(T[u].son[0],k); else return kth(T[u].son[1],k - T[T[u].son[0]].sum - 1);}void dfs(int u) { if (!u) return; push_down(u); dfs(T[u].son[0]); if (T[u].x != 0 && T[u].x != n+1) printf("%d ",T[u].x); dfs(T[u].son[1]);}int main() { scanf("%d%d",&n,&m); root = build(0,n+1); for (int ql,qr;m--;) { scanf("%d%d",&ql,&qr); ql = kth(root,ql); qr = kth(root,qr+2); splay(ql,0); splay(qr,ql); T[T[qr].son[0]].lazy ^= 1; } dfs(root); putchar(10);}
阅读全文
0 0
- zkw Splay学习笔记
- Splay学习笔记
- Splay学习笔记
- Splay Trees 学习笔记
- splay tree 学习笔记
- 【数据结构】Splay学习笔记
- splay 学习笔记
- Splay树 学习笔记一
- splay学习笔记及模板
- 学习笔记--(平衡树)splay
- 伸展树Splay学习笔记
- [学习笔记] bzoj3224 普通平衡树:splay模板
- Splay学习--初篇
- Splay Tree学习过程
- Splay学习总结
- splay学习小记
- Splay学习总结
- 【学习】Splay平衡树
- [牛客网] 拼凑三角形
- Netty:高性能、高可用的NIO通信框架
- 第二章--第三节 成本函数和损失函数推导过程
- Sql Line操作使用Hbase
- 逆向工具(待研究)
- splay 学习笔记
- 机器学习教程 之 SKlearn 中 PCA 算法的运用:人脸识别实例
- MediaRecorder官方文档导读
- seagull安装步骤
- Android Studio 使用 System.loadLibrary()的一些问题
- pytorch版的bilstm+crf实现sequence label
- C# 中绑定数据到datagridviewcomboboxcolumn
- java list随机取值
- 七扭八歪解faster rcnn(keras版)(二)