Splay模板(序列终结者)
Posted codedream
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Splay模板(序列终结者)相关的知识,希望对你有一定的参考价值。
我只是一个存模板的,详细的请看这里 http://blog.csdn.net/whai362/article/details/47298133
1 #include <cstdio> 2 #include <cstring> 3 #include <cctype> 4 #include <cmath> 5 #include <set> 6 #include <map> 7 #include <list> 8 #include <queue> 9 #include <deque> 10 #include <stack> 11 #include <string> 12 #include <vector> 13 #include <iostream> 14 #include <algorithm> 15 #include <stdlib.h> 16 #include <time.h> 17 using namespace std; 18 typedef long long LL; 19 const int INF = 2e9 + 1e8; 20 21 const int MOD = 1e9 + 7; 22 const double eps = 0.0000000001; 23 24 #define MSET(a, b) memset(a, b, sizeof(a)) 25 26 const int maxn = 1e6 + 10; 27 int max(int a, int b, int c) 28 { 29 return max(a, max(b, c)); 30 } 31 32 struct SplayTree 33 { 34 struct Node 35 { 36 int son[2], big, val, lazy, sz; 37 bool rev; 38 void init(int _val) 39 { 40 val = big = _val; 41 sz = 1; 42 lazy = rev = son[0] = son[1] = 0; 43 } 44 } T[maxn]; 45 int root, fa[maxn]; 46 void pushup(int i) 47 { 48 T[i].big=T[i].val,T[i].sz=1; 49 if(T[i].son[0]) 50 { 51 T[i].big=max(T[i].big,T[T[i].son[0]].big); 52 T[i].sz+=T[T[i].son[0]].sz; 53 } 54 if(T[i].son[1]) 55 { 56 T[i].big=max(T[i].big,T[T[i].son[1]].big); 57 T[i].sz+=T[T[i].son[1]].sz; 58 } 59 } 60 void pushdown(int i) 61 { 62 if (i == 0) 63 return; 64 if (T[i].lazy) 65 { 66 for (int k = 0; k < 2; k++) 67 { 68 if (T[i].son[k]) 69 { 70 T[T[i].son[k]].lazy += T[i].lazy; 71 T[T[i].son[k]].val += T[i].lazy; 72 T[T[i].son[k]].big += T[i].lazy; 73 } 74 } 75 T[i].lazy = 0; 76 } 77 if (T[i].rev) 78 { 79 for (int k = 0; k < 2; k++) 80 if (T[i].son[k]) 81 T[T[i].son[k]].rev ^= 1; 82 swap(T[i].son[0], T[i].son[1]); 83 T[i].rev = 0; 84 } 85 } 86 /** 旋转操作 87 * 传入x,旋转x与x的父亲这两个节点; 88 */ 89 void rotate(int x, int d) 90 { 91 int y = fa[x], z = fa[y]; 92 T[y].son[!d] = T[x].son[d], fa[T[x].son[d]] = y; 93 T[x].son[d] = y, fa[y] = x; 94 T[z].son[T[z].son[1] == y] = x, fa[x] = z; 95 pushup(y); 96 } 97 void splay(int x, int goal) 98 { 99 if (x == goal) 100 return; 101 while (fa[x] != goal) 102 { 103 int y = fa[x], z = fa[y]; 104 pushdown(z), pushdown(y), pushdown(x); 105 int dirx = (T[y].son[0] == x), diry = (T[z].son[0] == y); 106 if (z == goal) 107 rotate(x, dirx); 108 else 109 { 110 if (dirx == diry) 111 rotate(y, diry); 112 else 113 rotate(x, dirx); 114 rotate(x, diry); 115 } 116 } 117 pushup(x); 118 if (goal == 0) 119 root = x; 120 } 121 /** 122 * select(pos) 返回第pos+1个元素; 123 */ 124 int Select(int pos) 125 { 126 int u = root; 127 pushdown(u); 128 while (T[T[u].son[0]].sz != pos) 129 { 130 if (pos < T[T[u].son[0]].sz) 131 u = T[u].son[0]; 132 else 133 { 134 pos = pos - (1 + T[T[u].son[0]].sz); 135 u = T[u].son[1]; 136 } 137 pushdown(u); 138 } 139 return u; 140 } 141 void update(int l, int r, int val) 142 { 143 int x = Select(l - 1), y = Select(r + 1); 144 splay(x, 0); 145 splay(y, x); 146 T[T[y].son[0]].val += val; 147 T[T[y].son[0]].big += val; 148 T[T[y].son[0]].lazy += val; 149 } 150 void turn(int l, int r) 151 { 152 int x = Select(l - 1), y = Select(r + 1); 153 splay(x, 0); 154 splay(y, x); 155 T[T[y].son[0]].rev ^= 1; 156 } 157 int query(int l, int r) 158 { 159 int x = Select(l - 1), y = Select(r + 1); 160 splay(x, 0); 161 splay(y, x); 162 return T[T[y].son[0]].big; 163 } 164 int build(int L, int R) 165 { 166 if (L > R) 167 return 0; 168 if (L == R) 169 return L; 170 int mid = (L + R) >> 1, sL, sR; 171 T[mid].son[0] = sL = build(L, mid - 1); 172 T[mid].son[1] = sR = build(mid + 1, R); 173 fa[sL] = fa[sR] = mid; 174 pushup(mid); 175 return mid; 176 } 177 178 void init(int n) 179 { 180 T[0].init(-INF), T[1].init(-INF), T[n + 2].init(INF); 181 for (int i = 2; i <= n + 1; i++) 182 T[i].init(0); 183 root = build(1, n + 2), fa[root] = 0; 184 fa[0] = 0, T[0].son[1] = root, T[0].sz = 0; 185 } 186 } re; 187 188 int main() 189 { 190 int n, m; 191 scanf("%d%d", &n, &m); 192 re.init(n); 193 for (int i = 0, a, b, c, d; i < m; i++) 194 { 195 scanf("%d", &a); 196 if (a == 1) 197 { 198 scanf("%d%d%d", &b, &c, &d); 199 re.update(b, c, d); 200 } 201 else if (a == 2) 202 { 203 scanf("%d%d", &b, &c); 204 re.turn(b, c); 205 } 206 else 207 { 208 scanf("%d%d", &b, &c); 209 printf("%d\n", re.query(b, c)); 210 } 211 } 212 return 0; 213 } 214 215 /**************************************************/ 216 /** Copyright Notice **/ 217 /** writer: wurong **/ 218 /** school: nyist **/ 219 /** blog : http://blog.csdn.net/wr_technology **/ 220 /**************************************************/
以上是关于Splay模板(序列终结者)的主要内容,如果未能解决你的问题,请参考以下文章