这东西都没什么板子着实让我很难受啊,只能到网上抄抄补补,

  记下两个用到的博客

https://blog.csdn.net/clove_unique/article/details/50630280

https://blog.csdn.net/ophunter_lcm/article/details/18157185

  BZOJ 3224

  复制粘贴?...

  1. #include <iostream>
  2. #include <string.h>
  3. #include <cstdio>
  4. #include <vector>
  5. #include <queue>
  6. #include <math.h>
  7. #include <string>
  8. #include <algorithm>
  9. #include <time.h>
  10.  
  11. #define SIGMA_SIZE 26
  12. #define lson rt<<1
  13. #define rson rt<<1|1
  14. #define lowbit(x) (x&-x)
  15. #define foe(i, a, b) for(int i=a; i<=b; i++)
  16. #define fo(i, a, b) for(int i=a; i<b; i++);
  17. #pragma warning ( disable : 4996 )
  18.  
  19. using namespace std;
  20. typedef long long LL;
  21. inline LL LMax(LL a, LL b) { return a>b ? a : b; }
  22. inline LL LMin(LL a, LL b) { return a>b ? b : a; }
  23. inline LL lgcd(LL a, LL b) { return b == ? a : lgcd(b, a%b); }
  24. inline LL llcm(LL a, LL b) { return a / lgcd(a, b)*b; } //a*b = gcd*lcm
  25. inline int Max(int a, int b) { return a>b ? a : b; }
  26. inline int Min(int a, int b) { return a>b ? b : a; }
  27. inline int gcd(int a, int b) { return b == ? a : gcd(b, a%b); }
  28. inline int lcm(int a, int b) { return a / gcd(a, b)*b; } //a*b = gcd*lcm
  29. const LL INF = 0x3f3f3f3f3f3f3f3f;
  30. const LL mod = ;
  31. const double eps = 1e-;
  32. const int inf = 0x3f3f3f3f;
  33. const int maxk = 1e6 + ;
  34. const int maxn = 1e5 + ;
  35.  
  36. int Size, root;
  37. int ch[maxn<<][];
  38. int f[maxn<<];
  39. int key[maxn<<];
  40. int cnt[maxn<<];
  41. int siz[maxn<<];
  42.  
  43. inline void clear(int x)
  44. { ch[x][] = ch[x][] = f[x] = cnt[x] = key[x] = siz[x] = ; }
  45.  
  46. //判断当前点是它父节点的左儿子还是右儿子
  47. inline int get(int x)
  48. { return ch[f[x]][] == x; }
  49.  
  50. //更新当前点size值(用于修改之后)
  51. inline void update(int x)
  52. {
  53. if (x) {
  54. siz[x] = cnt[x];
  55. if (ch[x][]) siz[x] += siz[ch[x][]];
  56. if (ch[x][]) siz[x] += siz[ch[x][]];
  57. }
  58. }
  59.  
  60. inline void rotate(int x)
  61. {
  62. int old = f[x], oldf = f[old], which = get(x);
  63. ch[old][which] = ch[x][which^]; f[ch[old][which]] = old;
  64. f[old] = x; ch[x][which^] = old;
  65. f[x] = oldf;
  66. if (oldf)
  67. ch[oldf][ch[oldf][]==old] = x;
  68. update(old); update(x);
  69. }
  70.  
  71. inline void splay(int x)
  72. {
  73. for( int fa; (fa=f[x]); rotate(x))
  74. if ( f[fa] )
  75. rotate((get(x)==get(fa) ? fa : x));
  76. root = x;
  77. }
  78.  
  79. inline void insert(int v)
  80. {
  81. if ( root == )
  82. {
  83. Size++; ch[Size][] = ch[Size][] = f[Size] = ; key[Size] = v;
  84. cnt[Size] = ; siz[Size] = ; root = Size; return;
  85. }
  86.  
  87. int now = root, fa = ;
  88. while ()
  89. {
  90. if (key[now] == v) {
  91. cnt[now]++;
  92. update(now); update(fa);
  93. splay(now);
  94. break;
  95. }
  96. fa = now;
  97. now = ch[now][key[now]<v];
  98. if (now == ) {
  99. Size++;
  100. ch[Size][] = ch[Size][] = ;
  101. key[Size] = v; siz[Size] = ;
  102. cnt[Size] = ; f[Size] = fa;
  103. ch[fa][key[fa]<v] = Size;
  104. update(fa);
  105. splay(Size);
  106. break;
  107. }
  108. }
  109. }
  110.  
  111. inline int find(int v)
  112. {
  113. int ans = , now = root;
  114. while ()
  115. {
  116. if ( v < key[now] )
  117. now = ch[now][];
  118. else {
  119. ans += (ch[now][] ? siz[ch[now][]] : );
  120. if ( v == key[now] ) { splay(now); return ans+; }
  121.  
  122. ans += cnt[now];
  123. now = ch[now][];
  124. }
  125. }
  126. }
  127.  
  128. inline int findx(int x)
  129. {
  130. int now = root;
  131. while ()
  132. {
  133. if ( ch[now][] && x <= siz[ch[now][]] )
  134. now = ch[now][];
  135. else {
  136. int tmp = ( ch[now][] ? siz[ch[now][]] : ) + cnt[now];
  137.  
  138. if ( x <= tmp )
  139. return key[now];
  140. x -= tmp;
  141. now = ch[now][];
  142. }
  143. }
  144. }
  145.  
  146. inline int pre()
  147. {
  148. int now = ch[root][];
  149. while ( ch[now][] ) now = ch[now][];
  150. return now;
  151. }
  152.  
  153. inline int next()
  154. {
  155. int now = ch[root][];
  156. while ( ch[now][] ) now = ch[now][];
  157. return now;
  158. }
  159.  
  160. inline void del(int x) {
  161. int whatever = find(x);
  162. if (cnt[root]>) { cnt[root]--; return; }
  163. //Only One Point
  164. if (!ch[root][] && !ch[root][]) { clear(root); root = ; return; }
  165. //Only One Child
  166. if (!ch[root][]) {
  167. int oldroot = root; root = ch[root][]; f[root] = ; clear(oldroot); return;
  168. }
  169. else if (!ch[root][]) {
  170. int oldroot = root; root = ch[root][]; f[root] = ; clear(oldroot); return;
  171. }
  172. //Two Children
  173. int leftbig = pre(), oldroot = root;
  174. splay(leftbig);
  175. f[ch[oldroot][]] = root;
  176. ch[root][] = ch[oldroot][];
  177. clear(oldroot);
  178. update(root);
  179. return;
  180. }
  181.  
  182. int main()
  183. {
  184. int n, opt, x;
  185. scanf("%d", &n);
  186. for (int i = ; i <= n; ++i) {
  187. scanf("%d%d", &opt, &x);
  188. switch (opt) {
  189. case : insert(x); break;
  190. case : del(x); break;
  191. case : printf("%d\n", find(x)); break;
  192. case : printf("%d\n", findx(x)); break;
  193. case : insert(x); printf("%d\n", key[pre()]); del(x); break;
  194. case : insert(x); printf("%d\n", key[next()]); del(x); break;
  195. }
  196. }
  197.  
  198. return ;
  199. }

  BZOJ 1251(区间翻转和区间增加一个值V)

  这份代码比较清晰易懂

  https://blog.csdn.net/whai362/article/details/47298133(加了一些注释

  1. /*bzoj 1251 序列终结者
  2. 题意:
  3. 给定一个长度为N的序列,每个序列的元素是一个整数。要支持以下三种操作:
  4. 1. 将[L,R]这个区间内的所有数加上V;
  5. 2. 将[L,R]这个区间翻转,比如1 2 3 4变成4 3 2 1;
  6. 3. 求[L,R]这个区间中的最大值;
  7. 最开始所有元素都是0。
  8. 限制:
  9. N <= 50000, M <= 100000
  10. 思路:
  11. 伸展树
  12. 关键点:
  13. 1. 伸展树为左小右大的二叉树,所以旋转操作不会影响树的性质
  14. 2. 区间操作为:
  15. int u = select(L - 1), v = select(R + 1);
  16. splay(u, 0); splay(v, u); //通过旋转操作把询问的区间聚集到根的右子树的左子树下
  17. 因为伸展树为左小右大的二叉树,旋转操作后的所以对于闭区间[L, R]之间的所有元素都聚集在根的右子树的左子树下
  18. 因为闭区间[L, R],
  19. 1) 所以每次都要查开区间(L - 1, R + 1),
  20. 2) 所以伸展树元素1对应的标号为2,
  21. 3) 所以node[0]对应空节点,node[1]对应比所以元素标号都小的点,node[2 ~ n + 1]对应元素1 ~ n,node[n + 2]对应比所有元素标号都打的点,其中node[0], node[1], node[n + 2]都是虚节点,不代表任何元素。
  22. */
  23. #include <iostream>
  24. #include <string.h>
  25. #include <cstdio>
  26. #include <vector>
  27. #include <queue>
  28. #include <math.h>
  29. #include <string>
  30. #include <algorithm>
  31. #include <time.h>
  32.  
  33. #define SIGMA_SIZE 26
  34. #define lson rt<<1
  35. #define rson rt<<1|1
  36. #define lowbit(x) (x&-x)
  37. #define foe(i, a, b) for(int i=a; i<=b; i++)
  38. #define fo(i, a, b) for(int i=a; i<b; i++);
  39. #pragma warning ( disable : 4996 )
  40.  
  41. using namespace std;
  42. typedef long long LL;
  43. inline LL LMax(LL a, LL b) { return a>b ? a : b; }
  44. inline LL LMin(LL a, LL b) { return a>b ? b : a; }
  45. inline LL lgcd(LL a, LL b) { return b == ? a : lgcd(b, a%b); }
  46. inline LL llcm(LL a, LL b) { return a / lgcd(a, b)*b; } //a*b = gcd*lcm
  47. inline int Max(int a, int b) { return a>b ? a : b; }
  48. inline int Min(int a, int b) { return a>b ? b : a; }
  49. inline int gcd(int a, int b) { return b == ? a : gcd(b, a%b); }
  50. inline int lcm(int a, int b) { return a / gcd(a, b)*b; } //a*b = gcd*lcm
  51. const LL INF = 0x3f3f3f3f3f3f3f3f;
  52. const LL mod = ;
  53. const double eps = 1e-;
  54. const int inf = 0x3f3f3f3f;
  55. const int maxk = 1e6 + ;
  56. const int maxn = 1e5 + ;
  57.  
  58. #define LS(n) node[(n)].ch[0]
  59. #define RS(n) node[(n)].ch[1]
  60.  
  61. struct Splay {
  62. struct Node {
  63. int fa, ch[];
  64. bool rev;
  65. int val, add, maxx, size;
  66. void init(int _val) {
  67. val = maxx = _val;
  68. size = ;
  69. add = rev = ch[] = ch[] = ;
  70. }
  71. } node[maxn];
  72. int root;
  73.  
  74. ///相当于线段树的pushup和pushdown
  75. void pushUp(int n) {
  76. node[n].maxx = Max(node[n].val, Max(node[LS(n)].maxx, node[RS(n)].maxx));
  77. node[n].size = node[LS(n)].size + node[RS(n)].size + ;
  78. }
  79.  
  80. void pushDown(int n) {
  81. if (n == ) return;
  82. if (node[n].add) {
  83. if (LS(n)) {
  84. node[LS(n)].val += node[n].add;
  85. node[LS(n)].maxx += node[n].add;
  86. node[LS(n)].add += node[n].add;
  87. }
  88. if (RS(n)) {
  89. node[RS(n)].val += node[n].add;
  90. node[RS(n)].maxx += node[n].add;
  91. node[RS(n)].add += node[n].add;
  92. }
  93. node[n].add = ;
  94. }
  95. if (node[n].rev) {
  96. if (LS(n)) node[LS(n)].rev ^= ;
  97. if (RS(n)) node[RS(n)].rev ^= ;
  98. swap(LS(n), RS(n));
  99. node[n].rev = ;
  100. }
  101. }
  102.  
  103. ///kind = 0为左旋
  104. ///kind = 1为右旋
  105. void rotate(int n, bool kind) {
  106. int fn = node[n].fa;
  107. int ffn = node[fn].fa;
  108. node[fn].ch[!kind] = node[n].ch[kind];
  109. node[node[n].ch[kind]].fa = fn;
  110.  
  111. node[n].ch[kind] = fn;
  112. node[fn].fa = n;
  113.  
  114. node[ffn].ch[RS(ffn) == fn] = n;
  115. node[n].fa = ffn;
  116. pushUp(fn);
  117. }
  118.  
  119. void splay(int n, int goal) {
  120. while (node[n].fa != goal) {
  121. int fn = node[n].fa;
  122. int ffn = node[fn].fa;
  123. //三连pushDown
  124. pushDown(ffn); pushDown(fn); pushDown(n);
  125. bool rotate_n = (LS(fn) == n);
  126. bool rotate_fn = (LS(ffn) == fn);
  127. if (ffn == goal) rotate(n, rotate_n);
  128. else {
  129. if (rotate_n == rotate_fn) rotate(fn, rotate_fn);
  130. else rotate(n, rotate_n);
  131. rotate(n, rotate_fn);
  132. }
  133. }
  134. pushUp(n);
  135. if (goal == ) root = n;
  136. }
  137.  
  138. ///通过数组中的位置找在树中的位置
  139. int select(int pos) {
  140. int u = root;
  141. pushDown(u);
  142. while (node[LS(u)].size != pos) {
  143. if (pos < node[LS(u)].size)
  144. u = LS(u);
  145. else {
  146. pos -= node[LS(u)].size + ;
  147. u = RS(u);
  148. }
  149. pushDown(u);
  150. }
  151. return u;
  152. }
  153.  
  154. int query(int L, int R) {
  155. int u = select(L - ), v = select(R + );
  156. splay(u, ); splay(v, u); ///通过旋转操作把询问的区间聚集到根的右子树的左子树下
  157. return node[LS(v)].maxx;
  158. }
  159.  
  160. void pushUpdate(int L, int R, int val) {
  161. int u = select(L - ), v = select(R + );
  162. splay(u, ); splay(v, u);
  163. node[LS(v)].val += val;
  164. node[LS(v)].maxx += val;
  165. node[LS(v)].add += val;
  166. }
  167.  
  168. void reverse(int L, int R) {
  169. int u = select(L - ), v = select(R + );
  170. splay(u, ); splay(v, u);
  171. node[LS(v)].rev ^= ;
  172. }
  173.  
  174. ///返回子树的根节点
  175. int build(int L, int R) {
  176. if (L > R) return ;
  177. if (L == R) return L;
  178. int mid = (L + R) >> ;
  179. int r_L, r_R;
  180. LS(mid) = r_L = build(L, mid - );
  181. RS(mid) = r_R = build(mid + , R);
  182. node[r_L].fa = node[r_R].fa = mid;
  183. pushUp(mid);
  184. return mid;
  185. }
  186.  
  187. ///按照数组的下标顺序作为建树依据
  188. ///而不是按照数组内的元素大小做依据
  189. void init(int n) {
  190. ///0号节点最大值和值都是负无穷
  191. node[].init(-inf); node[].size = ;
  192. node[].init(-inf);
  193. node[n + ].init(-inf);
  194. for (int i = ; i <= n + ; ++i)
  195. node[i].init();
  196.  
  197. root = build(, n + );
  198. node[root].fa = ;
  199.  
  200. node[].fa = ;
  201. LS() = root;
  202. }
  203. } splay_tree;
  204.  
  205. int main() {
  206. int n, m;
  207. scanf("%d%d", &n, &m);
  208. splay_tree.init(n);
  209. for (int i = ; i < m; ++i) {
  210. int op, l, r, v;
  211. scanf("%d", &op);
  212. if (op == ) {
  213. scanf("%d%d%d", &l, &r, &v);
  214. splay_tree.pushUpdate(l, r, v);
  215. }
  216. else if (op == ) {
  217. scanf("%d%d", &l, &r);
  218. splay_tree.reverse(l, r);
  219. }
  220. else {
  221. scanf("%d%d", &l, &r);
  222. printf("%d\n", splay_tree.query(l, r));
  223. }
  224. }
  225. return ;
  226. }

初识splay的更多相关文章

  1. [洛谷P3391] 文艺平衡树 (Splay模板)

    初识splay 学splay有一段时间了,一直没写...... 本题是splay模板题,维护一个1~n的序列,支持区间翻转(比如1 2 3 4 5 6变成1 2 3 6 5 4),最后输出结果序列. ...

  2. BZOJ 3223: Tyvj 1729 文艺平衡树

    3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3628  Solved: 2052[Submit][Sta ...

  3. Android动画效果之初识Property Animation(属性动画)

    前言: 前面两篇介绍了Android的Tween Animation(补间动画) Android动画效果之Tween Animation(补间动画).Frame Animation(逐帧动画)Andr ...

  4. 初识Hadoop

    第一部分:              初识Hadoop 一.             谁说大象不能跳舞 业务数据越来越多,用关系型数据库来存储和处理数据越来越感觉吃力,一个查询或者一个导出,要执行很长 ...

  5. python学习笔记(基础四:模块初识、pyc和PyCodeObject是什么)

    一.模块初识(一) 模块,也叫库.库有标准库第三方库. 注意事项:文件名不能和导入的模块名相同 1. sys模块 import sys print(sys.path) #打印环境变量 print(sy ...

  6. 初识IOS,Label控件的应用。

    初识IOS,Label控件的应用. // // ViewController.m // Gua.test // // Created by 郭美男 on 16/5/31. // Copyright © ...

  7. UI篇(初识君面)

    我们的APP要想吸引用户,就要把UI(脸蛋)搞漂亮一点.毕竟好的外貌是增进人际关系的第一步,我们程序员看到一个APP时,第一眼就是看这个软件的功能,不去关心界面是否漂亮,看到好的程序会说"我 ...

  8. Python导出Excel为Lua/Json/Xml实例教程(一):初识Python

    Python导出Excel为Lua/Json/Xml实例教程(一):初识Python 相关链接: Python导出Excel为Lua/Json/Xml实例教程(一):初识Python Python导出 ...

  9. BZOJ 1251: 序列终结者 [splay]

    1251: 序列终结者 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 3778  Solved: 1583[Submit][Status][Discu ...

随机推荐

  1. JAVA数据结构之哈希表

    Hash表简介: Hash表是基于数组的,优点是提供快速的插入和查找的操作,编程实现相对容易,缺点是一旦创建就不好扩展,当hash表被基本填满的时候,性能下降非常严重(发生聚集引起的性能的下降),而且 ...

  2. if else 和 swith效率比较

    读大话设计模式,开头的毛病代码用if else实现了计算器,说计算机做了三次无用功,优化后是用switch,那么switch为什么比if else效率高呢, 百度找了几个说是底层算法不一样,找了一个比 ...

  3. 固定定位fixed,绝对定位absolute,相对定位relative;以及overflow

    固定定位position:fixed /*固定定位 1.定位属性值:fixed 2.在页面中不再占位(浮起来了) 3.一旦定位后,定位的布局方位 top.bottom.left.right都能参与布局 ...

  4. JS 基本的介绍

    JS中的注释   HTML的注释:<!—注释内容-->   CSS注释:/* 注释 */   JavaScript的注释:// 或 /*  多行注释 */ 变量 1.变量的概念 变量是变化 ...

  5. fastjson 过滤不需要序列化的属性

    JSON JSON英文全称为JavaScriptObject Natation,采用key:value键值对的方式存贮数据,与xml格式相比,JSON是一种轻量级的数据交换格式:不要被JavaScri ...

  6. STM32F103 Feature

  7. <Python基础>集合的基本操作

    #小知识点:返回对象的内存地址 i,j = 1,2 print(id(i),id(j)) #集合的基本操作, #相当于没有键值对的字典,里面的元素是无序且不重复的 #一般写法 s = set({1,2 ...

  8. Win10命令提示符git log中文乱码的解决方案

    在系统环境变量中新建一个名为LESSCHARSET的变量 其值为utf-8 新建完毕后应用,git log就不会出现乱码的问题了^_^ 参考博文:git- win10 cmd git log 中文乱码 ...

  9. 连接RDS数据库

  10. 单体内置对象——Global对象

    单体内置对象的定义:由ECMAScript实现提供的.不依赖于宿主环境的对象,这些对象在ECMAScript程序执行之前已经存在了.意思就是说:开发人员不必显式地实例化内置对象,因为他们已经实例化了. ...