http://www.lydsy.com/JudgeOnline/problem.php?id=1861
寫好關鍵的三個函數後就是水水的類比題,旋轉來旋轉去的操作,so easy
有幾點值得注意:
1:取出Splay中某個節點,然後在插回去,這個節點的左右兒子要記得清空
2:每次更改關係後別忘了up上去
沒了。。
#include <cstdio>#include <cstring>#include <queue>#include <stack>#include <vector>#include <set>#include <algorithm>using namespace std;typedef long long lld;#define L x->c[0]#define R x->c[1]#define KT root->c[1]->c[0]const int maxn = 111111;struct node { struct node *c[2], *fa; int id; int sz; int val; inline bool d() { return fa->c[0] == this; } inline void setc(int d, node *s) { c[d] = s; s->fa = this; } inline void up() { sz = c[0]->sz + c[1]->sz + 1; } inline void clear(node *null) { c[0] = c[1] = null; sz = 1; }} NODE[2 * maxn], *null = &NODE[0] ;int top;node* ID[maxn];struct SplayTree { node* root; void Rotate(node *x,int f) { node *y = x->fa; y->setc(!f,x->c[f]); x->fa = y->fa; if (y->fa != null) y->fa->setc(!y->d(),x); x->setc(f,y); y->up(); } void Splay(node *x, node *goal) { while (x->fa != goal) { if (x->fa->fa == goal) Rotate(x, x->d()); else { int f = x->fa->d(); x->d() == f ? Rotate(x->fa, f) : Rotate(x, !f); Rotate(x, f); } } x->up(); if (goal == null) root = x; } void RTO(int k, node *goal) { if(k<1||k>root->sz) while(1); node *x = root; while (L->sz + 1 != k) { if(k < L->sz + 1) x = L; else { k -= L->sz + 1; x = R; } } Splay(x, goal); } void build(node* &x,int l,int r,node *fa) { if(l > r) return ; int m = l + r >>1; x = new_node(fa,num[m]); build(x->c[0],l,m-1,x); build(x->c[1],m+1,r,x); x->up(); } node *new_node(node *fa, int v) { node *x = &NODE[++top]; x->id = top; x->c[0] = x->c[1] = null; x->sz = 1; x->val = v; x->fa = fa; if(v!=-1) ID[v] = x; return x; } void init(int n) { for(int i = 1; i <= n; i++) scanf("%d",&num[i]); root = new_node(null,-1); build(root->c[1],1,n,root); root->up(); } void Del_root() { // delete the root node* t = root; if (t->c[1] != null) { root = t->c[1]; RTO(1, null); root->c[0] = t->c[0]; if (root->c[0] != null) root->c[0]->fa = root; } else root = root->c[0]; root->fa = null; if (root != null) root->up(); } void Insert(int p,int v) { Splay(ID[p],null); int NC = root->c[0]->sz - 1; Del_root(); ID[p]->clear(null); NC += v; RTO(NC+1,null); if(root->c[1] == null) { root->setc(1,ID[p]); root->up(); return ; } RTO(NC+2,root); root->c[1]->setc(0,ID[p]); root->c[1]->up(); root->up(); } void Bottom(int p) { Splay(ID[p],null); Del_root(); ID[p]->clear(null); RTO(root->sz,null); root->setc(1,ID[p]); root->up(); } void Top(int p) { Splay(ID[p],null); Del_root(); ID[p]->clear(null); RTO(1,null); if(root->c[1] == null) { root->setc(1,ID[p]); return ; } RTO(2,root); root->c[1]->setc(0,ID[p]); root->c[1]->up(); root->up(); } int Query(int p) { RTO(p+1,null); return root->val; } int Ask(int p) { Splay(ID[p],null); return root->c[0]->sz - 1; } void vist(node *x) { if (x != null) { printf("節點:%2d : 左兒子: %2d 右兒子: %2d sz: %2d val: %d\n", x->id,x->c[0]->id,x->c[1]->id,x->sz,x->val); vist(x->c[0]); vist(x->c[1]); } } void debug() { puts("************"); vist(root); puts("\n*****************"); } int num[maxn];} spt;void prepare() { top = 0; null->id = 0; null->c[0] = null->c[1] = null->fa = NULL; null->sz = 0; null->val = 0;}int main() { char op[10]; prepare(); int n , m , p; scanf("%d%d",&n,&m); spt.init(n); while(m--) { scanf("%s",op); if(op[0] == 'Q') { scanf("%d",&p); printf("%d\n",spt.Query(p)); } else if(op[0] == 'A') { scanf("%d",&p); printf("%d\n",spt.Ask(p)); } else if(op[0] == 'B') { scanf("%d",&p); spt.Bottom(p); } else if(op[0] == 'T') { scanf("%d",&p); spt.Top(p); } else { int v; scanf("%d%d",&p,&v); spt.Insert(p,v); } } return 0;}