1. 程式人生 > >【樹】【平衡樹】Splay自頂向下模板

【樹】【平衡樹】Splay自頂向下模板

操作1插入x
操作2刪除x
操作3查詢x排名
操作4查詢排名為x的數
操作5查詢x的前驅
操作6查詢x的後繼

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
struct node{
    int sz, val;
    node *ch[2];
    node(){ch[0] = ch[1] = this; val = sz = 0;}
    node *resize(){return sz=ch[0]->sz+ch[1]->sz+1
, this;} }Tnull, *nil=&Tnull, *root; node *newnode(node *lch, node *rch, int v){ node *ret = new node; ret->val = v; ret->ch[0] = lch, ret->ch[1] = rch; return ret; } void build(){root = (newnode(nil, nil, 100000000))->resize();} void Zig(bool d){ node *tmp = root->ch[d]; root->ch[d] = nil
->ch[d]; nil->ch[d] = root; root = tmp; } void ZigZig(bool d){ node *tmp = root->ch[d]->ch[d]; root->ch[d]->ch[d] = nil->ch[d]; nil->ch[d] = root->ch[d]; root->ch[d] = nil->ch[d]->ch[!d]; nil->ch[d]->ch[!d] = root->resize(); root = tmp; } void
Finish(bool d){ node *p=root->ch[!d], *t=nil->ch[d]; while(t != nil){ t = nil->ch[d]->ch[d]; nil->ch[d]->ch[d] = p; p = nil->ch[d]->resize(); nil->ch[d] = t; } root->ch[!d] = p; } void Select(int u){ bool d, dd; int t; while(true){ d = (t = root->ch[0]->sz) < u; if(t == u || root->ch[d] == nil) break; if(d) u -= t + 1; dd = (t = root->ch[d]->ch[0]->sz) < u; if(t == u || root->ch[d]->ch[dd] == nil){Zig(d);break;} if(dd) u -= t + 1; if(d == dd) ZigZig(dd); else Zig(d), Zig(dd); } Finish(0); Finish(1); root->resize(); } void Search(int u){ bool d, dd; while(true){ d = root->val < u; if(root->ch[d] == nil) break; dd = root->ch[d]->val < u; if(root->ch[d]->ch[dd] == nil){Zig(d); break;} if(d == dd) ZigZig(dd); else Zig(d), Zig(dd); } Finish(0); Finish(1); root->resize(); if(root->val < u) Select(root->ch[0]->sz+1); } void Insert(int v){ Search(v); node *newroot = newnode(root->ch[0], root, v); root->ch[0] = nil; root->resize(); root = newroot->resize(); } void Delete(int v){ Search(v); if(root->val != v) return ; node *oldroot = root; root = oldroot->ch[1]; Select(0); root->ch[0] = oldroot->ch[0]; root->resize(); delete oldroot; } int XRank(int x){ Select(x-1); return root->val; } int FRank(int x){ Search(x); return root->ch[0]->sz+1; } int Pre(int x){ Search(x); Select(root->ch[0]->sz-1); return root->val; } int Bak(int x){ Search(x); if(root->val != x) return root->val; Search(x+1); return root->val; } int main(){ build(); int n, ord, x; scanf("%d", &n); for(int i=1;i<=n;i++){ scanf("%d%d", &ord, &x); switch(ord){ case 1: Insert(x); break; case 2: Delete(x); break; case 3: printf("%d\n", FRank(x)); break; case 4: printf("%d\n", XRank(x)); break; case 5: printf("%d\n", Pre(x)); break; case 6: printf("%d\n", Bak(x)); break; } } return 0; }