初识splay
Posted chaoswr
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了初识splay相关的知识,希望对你有一定的参考价值。
这东西都没什么板子着实让我很难受啊,只能到网上抄抄补补,
记下两个用到的博客
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 == 0 ? 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 == 0 ? 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 = 1000000007; 31 const double eps = 1e-8; 32 const int inf = 0x3f3f3f3f; 33 const int maxk = 1e6 + 5; 34 const int maxn = 1e5 + 5; 35 36 int Size, root; 37 int ch[maxn<<2][2]; 38 int f[maxn<<2]; 39 int key[maxn<<2]; 40 int cnt[maxn<<2]; 41 int siz[maxn<<2]; 42 43 inline void clear(int x) 44 { ch[x][0] = ch[x][1] = f[x] = cnt[x] = key[x] = siz[x] = 0; } 45 46 //判断当前点是它父节点的左儿子还是右儿子 47 inline int get(int x) 48 { return ch[f[x]][1] == x; } 49 50 //更新当前点size值(用于修改之后) 51 inline void update(int x) 52 { 53 if (x) { 54 siz[x] = cnt[x]; 55 if (ch[x][0]) siz[x] += siz[ch[x][0]]; 56 if (ch[x][1]) siz[x] += siz[ch[x][1]]; 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^1]; f[ch[old][which]] = old; 64 f[old] = x; ch[x][which^1] = old; 65 f[x] = oldf; 66 if (oldf) 67 ch[oldf][ch[oldf][1]==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 == 0 ) 82 { 83 Size++; ch[Size][0] = ch[Size][1] = f[Size] = 0; key[Size] = v; 84 cnt[Size] = 1; siz[Size] = 1; root = Size; return; 85 } 86 87 int now = root, fa = 0; 88 while (1) 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 == 0) { 99 Size++; 100 ch[Size][0] = ch[Size][1] = 0; 101 key[Size] = v; siz[Size] = 1; 102 cnt[Size] = 1; 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 = 0, now = root; 114 while (1) 115 { 116 if ( v < key[now] ) 117 now = ch[now][0]; 118 else { 119 ans += (ch[now][0] ? siz[ch[now][0]] : 0); 120 if ( v == key[now] ) { splay(now); return ans+1; } 121 122 ans += cnt[now]; 123 now = ch[now][1]; 124 } 125 } 126 } 127 128 inline int findx(int x) 129 { 130 int now = root; 131 while (1) 132 { 133 if ( ch[now][0] && x <= siz[ch[now][0]] ) 134 now = ch[now][0]; 135 else { 136 int tmp = ( ch[now][0] ? siz[ch[now][0]] : 0) + cnt[now]; 137 138 if ( x <= tmp ) 139 return key[now]; 140 x -= tmp; 141 now = ch[now][1]; 142 } 143 } 144 } 145 146 inline int pre() 147 { 148 int now = ch[root][0]; 149 while ( ch[now][1] ) now = ch[now][1]; 150 return now; 151 } 152 153 inline int next() 154 { 155 int now = ch[root][1]; 156 while ( ch[now][0] ) now = ch[now][0]; 157 return now; 158 } 159 160 161 inline void del(int x) { 162 int whatever = find(x); 163 if (cnt[root]>1) { cnt[root]--; return; } 164 //Only One Point 165 if (!ch[root][0] && !ch[root][1]) { clear(root); root = 0; return; } 166 //Only One Child 167 if (!ch[root][0]) { 168 int oldroot = root; root = ch[root][1]; f[root] = 0; clear(oldroot); return; 169 } 170 else if (!ch[root][1]) { 171 int oldroot = root; root = ch[root][0]; f[root] = 0; clear(oldroot); return; 172 } 173 //Two Children 174 int leftbig = pre(), oldroot = root; 175 splay(leftbig); 176 f[ch[oldroot][1]] = root; 177 ch[root][1] = ch[oldroot][1]; 178 clear(oldroot); 179 update(root); 180 return; 181 } 182 183 int main() 184 { 185 int n, opt, x; 186 scanf("%d", &n); 187 for (int i = 1; i <= n; ++i) { 188 scanf("%d%d", &opt, &x); 189 switch (opt) { 190 case 1: insert(x); break; 191 case 2: del(x); break; 192 case 3: printf("%d ", find(x)); break; 193 case 4: printf("%d ", findx(x)); break; 194 case 5: insert(x); printf("%d ", key[pre()]); del(x); break; 195 case 6: insert(x); printf("%d ", key[next()]); del(x); break; 196 } 197 } 198 199 200 return 0; 201 }
以上是关于初识splay的主要内容,如果未能解决你的问题,请参考以下文章
初识Spring源码 -- doResolveDependency | findAutowireCandidates | @Order@Priority调用排序 | @Autowired注入(代码片段
初识OpenGL 片段着色器(Fragment Shader)