Splay Tree 支持的之中操作。
插入,删除,求前驱和后即,区间更新与查询。
先来一发Splay Tree最基础的操作——伸展,顺便求前驱和后即。[HNOI2002]营业额统计。
白书上讲的貌似要讨论目标节点,父节点,父节点的父节点,这三个节点之间的关系。
没太看懂,直接按照自己想得来了。
#include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <cmath> #include <stack> #include <map> #pragma comment(linker, "/STACK:1024000000"); #define EPS (1e-8) #define LL long long #define ULL unsigned long long LL #define _LL __int64 #define _INF 0x3f3f3f3f #define Mod 1000000007 using namespace std; const int MAXN = 100100; struct N { int data,son[2],pre; }st[MAXN*2]; int Top; void Rotate(int root,int pre,int dir) { N temp = st[pre]; temp.son[dir] = st[root].son[!dir]; st[pre] = st[root]; st[pre].son[!dir] = root; st[root] = temp; st[pre].pre = temp.pre; st[st[pre].son[0]].pre = pre; st[st[pre].son[1]].pre = pre; st[st[root].son[0]].pre = root; st[st[root].son[1]].pre = root; } //将目标节点旋转到goal下面,若goal == -1,则表示为将目标节点旋转到根节点。 void Splay(int root,int goal) { while(st[root].pre != goal) { Rotate(root,st[root].pre,st[st[root].pre].son[0] == root ? 0 : 1); root = st[root].pre; } } bool Insert(int &root,int x,int pre) { if(root == -1 || st[root].data == -1) { if(root == -1) root = Top++; st[root].pre = pre; st[root].data = x; st[root].son[0] = -1; st[root].son[1] = -1; if(x != -1) { Insert(st[root].son[0],-1,root); Insert(st[root].son[1],-1,root); Splay(root,-1); } return true; } if(x == st[root].data) return false; if(x < st[root].data) return Insert(st[root].son[0],x,root); else return Insert(st[root].son[1],x,root); } int Search_Min(int root) { if(st[st[root].son[0]].data == -1) return st[root].data; return Search_Min(st[root].son[0]); } int Search_Max(int root) { if(st[st[root].son[1]].data == -1) return st[root].data; return Search_Max(st[root].son[1]); } int main() { //freopen("data.txt","r",stdin); int n,x,i; int root; int sum; int MAX = ((1<<30)-1)*2+1; scanf("%d",&n); sum = 0; root = -1; for(i = 1; i <= n; ++i) { if(scanf("%d",&x) == EOF) x = 0; if(Insert(root,x,-1) == false) continue; int temp = MAX; if(st[st[root].son[0]].data != -1) temp = min(temp,abs(Search_Max(st[root].son[0])-st[root].data)); if(st[st[root].son[1]].data != -1) temp = min(temp,abs(Search_Min(st[root].son[1])-st[root].data)); sum += (temp == MAX ? x : temp); } printf("%d\n",sum); return 0; }
初涉Splay Tree
时间: 2024-10-20 15:18:24