【待补】splay 模板
- #define _CRT_SECURE_NO_WARNINGS
- #include<cmath>
- #include<iostream>
- #include<stdio.h>
- #include<algorithm>
- #include<map>
- #include<string.h>
- using namespace std;
- #define rep(i,t,n) for(int i =(t);i<=(n);++i)
- #define per(i,n,t) for(int i =(n);i>=(t);--i)
- #define mmm(a,b) memset(a,b,sizeof(a))
- #define ls(n) node[n].ch[0]
- #define rs(n) node[n].ch[1]
- const int N = ;
- const int INF = 0x3f3f3f3f;
- struct Splay {
- struct Node {
- int fa, ch[];
- bool flip;
- int v, add, maxn, s;
- void init(int val)
- {
- v = maxn = val;
- s = ;
- add = flip = ch[] = ch[] = ;
- }
- }node[N];
- int root;
- //维护一个结点
- void pushup(int n)
- {
- node[n].maxn = max(node[n].v, max(node[ls(n)].maxn, node[rs(n)].maxn));
- node[n].s = node[ls(n)].s + node[rs(n)].s + ;
- }
- //标记向下传
- void pushdown(int n)
- {
- if (n == ) return;
- if (node[n].add) {
- if (ls(n)) {
- node[ls(n)].v += node[n].add;
- node[ls(n)].maxn += node[n].add;
- node[ls(n)].add += node[n].add;
- }
- if (rs(n)) {
- node[rs(n)].v += node[n].add;
- node[rs(n)].maxn += node[n].add;
- node[rs(n)].add += node[n].add;
- }
- node[n].add = ;
- }
- if (node[n].flip) {
- if (ls(n)) node[ls(n)].flip ^= ;
- if (rs(n)) node[rs(n)].flip ^= ;
- swap(ls(n), rs(n));
- node[n].flip = ;
- }
- }
- //旋转
- void rotate(int n, int d)
- {
- int fn = node[n].fa;
- int ffn = node[fn].fa;
- node[fn].ch[d ^ ] = node[n].ch[d];
- node[node[n].ch[d]].fa = fn;
- node[n].ch[d] = fn;
- node[fn].fa = n;
- node[ffn].ch[rs(ffn) == fn] = n;
- node[n].fa = ffn;
- pushup(fn);
- }
- //将结点n转到goal下
- void splay(int n, int goal)
- {
- while (node[n].fa != goal)
- {
- int fn = node[n].fa;
- int ffn = node[fn].fa;
- pushdown(ffn), pushdown(fn), pushdown(n);
- bool d = (ls(fn) == n);
- bool d1 = (ls(ffn) == fn);
- if (ffn == goal) rotate(n, d);
- else
- {
- if (d == d1) rotate(fn, d1); else rotate(n, d);
- rotate(n, d1);
- }
- }
- pushup(n);
- if (goal == ) root = n;
- }
- //找寻中序遍历中的第pos个结点
- int select(int pos)
- {
- int u = root;
- pushdown(u);
- while (node[ls(u)].s != pos)
- {
- if (pos < node[ls(u)].s) u = ls(u);
- else
- {
- pos -= node[ls(u)].s + ;
- u = rs(u);
- }
- pushdown(u);
- }
- return u;
- }
- //查询l~r最大值
- int query(int l, int r)
- {
- int u = select(l - ), v = select(r + );
- splay(u, ); splay(v, u);
- return node[ls(v)].maxn;
- }
- //给l~r加上val
- void update(int l, int r, int val)
- {
- int u = select(l - ), v = select(r + );
- splay(u, ); splay(v, u);
- node[ls(v)].v += val;
- node[ls(v)].maxn += val;
- node[ls(v)].add += val;
- }
- //翻转l~r
- void reverse(int l, int r)
- {
- int u = select(l - ), v = select(r + );
- splay(u, ); splay(v, u);
- node[ls(v)].flip ^= ;
- }
- //类似二分来建树,就是这段代码现在的我还不会用指针来替换
- int build(int l, int r)
- {
- if (l > r) return ;
- if (l == r) return l;
- int mid = (l + r) >> ;
- int L, R;
- ls(mid) = L = build(l, mid - );
- rs(mid) = R = build(mid + , r);
- node[L].fa = node[R].fa = mid;
- pushup(mid);
- return mid;
- }
- //初始化
- void init(int n)
- {
- node[].init(-INF); node[].s = ;
- node[].init(-INF);
- node[n + ].init(-INF);
- for (int i = ; i <= n + ; i++)
- node[i].init();
- root = build(, n + );
- node[root].fa = node[].fa = ;
- ls() = root;
- }
- }splay_tree;
- int main()
- {
- int n, m;
- scanf("%d%d", &n, &m);
- splay_tree.init(n);
- for (int i = ; i < m; i++)
- {
- int opt, l, r, v;
- scanf("%d%d%d", &opt, &l, &r);
- if (opt == ) { scanf("%d", &v); splay_tree.update(l, r, v); }
- if (opt == ) splay_tree.reverse(l, r);
- if (opt == ) printf("%d\n", splay_tree.query(l, r));
- }
- return ;
- }
- /*
- const int maxn = 55;
- const int inf = 1e9 + 5;
- ll n,m;
- struct splay_tree {
- struct node {
- int val, mx, add, sz, son[2];
- bool rev;
- void init(int _val) { val = mx = _val, sz = 1, add = rev = son[0] = son[1]; }
- }T[maxn];
- int fa[maxn], root;
- void Rotate(int x, int kind) {
- int y = fa[x], z = fa[y];
- T[y].son[!kind] = T[x].son[kind], fa[T[x].son[kind]] = y;
- T[x].son[kind] = y, fa[y] = x;
- T[z].son[T[z].son[1] == y] = x, fa[x] = z;//orz
- }
- void Splay(int x,)
- };
- string s[maxn];
- map<char, int> mmp;
- int main()
- {
- cin >> n >> m;
- hehe.init();
- for (int i = 0, a, b, c, d; i < m; i++) {
- scanf("%d", &a);
- if (a == 1) { scanf("%d%d%d", &b, &c, &d); hehe.update(b, c, d); }
- else if (a == 2) { scanf("%d%d", &b, &c); hehe.Reverse(b, c); }
- else { scanf("%d%d", &b, &c); printf("%d\n"); hehe.query(b, c); }
- }
- return 0;
- }*/
【待补】splay 模板的更多相关文章
- bzoj 1588 splay模板题
用晚自习学了一下splay模板,没想象中那么难,主要是左旋和右旋可以简化到一个函数里边,减少代码长度... #include<iostream> #include<cstdio> ...
- COJ 1002 WZJ的数据结构(二)(splay模板)
我的LCC,LCT,Splay格式终于统一起来了... 另外..这个形式的Splay是标准的Splay(怎么鉴别呢?看Splay函数是否只传了一个变量node就行),刘汝佳小白书的Splay写的真是不 ...
- Splay 模板
Splay 模板 struct SplayTree{ const static int maxn = 1e5 + 15; int ch[maxn][2] , key[maxn] , s[maxn] , ...
- [luogu3369/bzoj3224]普通平衡树(splay模板、平衡树初探)
解题关键:splay模板题整理. 如何不加入极大极小值?(待思考) #include<cstdio> #include<cstring> #include<algorit ...
- BZOJ1588 [HNOI2002]营业额统计 splay模板
1588: [HNOI2002]营业额统计 Time Limit: 5 Sec Memory Limit: 162 MB Submit: 16189 Solved: 6482 [Submit][S ...
- 文艺平衡树(splay模板)
题干:splay模板,要求维护区间反转. splay是一种码量小于treap,但支持排名,前驱后继等treap可求的东西,也支持区间反转的平衡树. 但是有两个坏处: 1.splay常数远远大于trea ...
- [洛谷P3391] 文艺平衡树 (Splay模板)
初识splay 学splay有一段时间了,一直没写...... 本题是splay模板题,维护一个1~n的序列,支持区间翻转(比如1 2 3 4 5 6变成1 2 3 6 5 4),最后输出结果序列. ...
- bzoj 1208 splay模板题2
自己yy了找前驱和后继,学了学怎么删除...(反正就是练模板) #include<iostream> #include<cstdio> #include<cstring& ...
- 【BZOJ 3196】二逼平衡树 线段树套splay 模板题
我写的是线段树套splay,网上很多人写的都是套treap,然而本蒟蒻并不会treap 奉上sth神犇的模板: //bzoj3196 二逼平衡树,支持修改某个点的值,查询区间第k小值,查询区间某个值排 ...
随机推荐
- JAVA代码实现多级树结构封装对象
树结构在开发中经常遇到.例如:部门.菜单.员工架构等等.下面用部门作为例子构造部门结构树 1.部门表:dept -- ---------------------------- -- Table str ...
- Kubernetes1.2如何使用iptables
转:http://blog.csdn.net/horsefoot/article/details/51249161 本次分析的kubernetes版本号:v1.2.1-beta.0. Kubernet ...
- JAVA 线程池架构浅析
经历了Java内存模型.JUC基础之AQS.CAS.Lock.并发工具类.并发容器.阻塞队列.atomic类后,我们开始JUC的最后一部分:线程池.在这个部分你将了解到下面几个部分: 线程池的基础架构 ...
- File 类的 getCanonicalFile( ) 和 getAbsoluteFile( ) 区别
一.打开java.io.File源码,看下两个方法的区别 getAbsoluteFile public File getAbsoluteFile() { String absPath = getAbs ...
- git push origin master和git push有什么区别?
1.master是主分支,还可以建一些其他的分支用于开发.2.git push origin master的意思就是上传本地当前分支代码到master分支.git push是上传本地所有分支代码到远程 ...
- linux选择sdb sdb4 fat32 还是sda分区
fat32是怎么混到它们中的sda,sdb,sdc是你的第一块,第二块,第三块硬盘sda1,sda2,sda5是你第一块硬盘中的第一块分区,2块,5块分区fat32,ext2,ext3,ext4是你的 ...
- 浅析C#中的结构体和类
类和结构是 .NET Framework 中的常规类型系统的两种基本构造. 两者在本质上都属于数据结构.封装着一组总体作为一个逻辑单位的数据和行为. 数据和行为是该类或结构的"成员" ...
- 一个Login页面全面了解session与cookie
背景 做了四年的前端开发,对外一直说自己是web开发,那么身为一个web开发怎能不知道session与cookie以及其管理方式呢~ Login涉及技术栈:Nodejs,MongoDB,Express ...
- 解决java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone
使用spring boot整合MySQL时一直报 java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecog ...
- Python默认参数的坑
默认参数的坑 定义一个函数,传入一个list,添加一个end再返回 def add_end(L=[]): L.append('END') return L 正常调用时,结果似乎不错 print add ...