开始以为splay就是普通的BST,后来看了hh神和撞神的文章才知道splay可以当做线段树用,而且还可以完成区间插入和区间删除等这些线段树完成不了的工作,及其的灵活.
Daniel Sleator & Robert Tarjan & ACMer & OIer ORZ
poj 3667
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <queue> #include <algorithm> #include <vector> #include <cstring> #include <stack> #include <cctype> #include <utility> #include <map> #include <string> #include <climits> #include <set> #include <string> #include <sstream> #include <utility> #include <ctime> using std::priority_queue; using std::vector; using std::swap; using std::stack; using std::sort; using std::max; using std::min; using std::pair; using std::map; using std::string; using std::cin; using std::cout; using std::set; using std::queue; using std::string; using std::istringstream; using std::getline; using std::make_pair; using std::greater; const int MAXN(50010); int n; template<typename T1, typename T2> struct SPLAY_TREE { struct NODE { T1 key; T2 cover; T2 color; int size; T2 lsum, rsum, msum; NODE *fa; NODE *ch[2]; }; NODE *root, *NIL, *rear; NODE pool[MAXN]; void init() { NIL = pool; NIL->fa = NIL; NIL->ch[0] = NIL; NIL->ch[1] = NIL; NIL->key = -1; NIL->cover = -1; NIL->color = NIL->size = NIL->lsum = NIL->rsum = NIL->msum = 0; rear = pool+1; newnode(root, NIL, 0, 1); newnode(root->ch[1], root, n+1, 1); build_tree(1, n, root->ch[1]->ch[0], root->ch[1]); push_up(root->ch[1]); push_up(root); } void newnode(NODE *&sour, NODE *f, const T1 &value1, const T2 &value2) { rear->key = value1; rear->cover = -1; rear->color = value2; rear->ch[0] = rear->ch[1] = NIL; rear->fa = f; rear->size = 1; sour = rear++; } void push_up(NODE *sour) { sour->lsum = sour->ch[0]->lsum; sour->rsum = sour->ch[1]->rsum; if(sour->lsum == sour->ch[0]->size && sour->color != 1) sour->lsum += sour->ch[1]->lsum+1; if(sour->rsum == sour->ch[1]->size && sour->color != 1) sour->rsum += sour->ch[0]->rsum+1; sour->msum = max(sour->ch[0]->msum, sour->ch[1]->msum); if(sour->color != 1) sour->msum = max(sour->msum, sour->ch[0]->rsum+sour->ch[1]->lsum+1); sour->size = sour->ch[0]->size+sour->ch[1]->size+1; } void push_down(NODE *sour) { if(sour->cover != -1) { sour->ch[0]->cover = sour->ch[0]->color = sour->cover; sour->ch[1]->cover = sour->ch[1]->color = sour->cover; sour->ch[0]->lsum = sour->ch[0]->rsum = sour->ch[0]->msum = sour->cover? 0: sour->ch[0]->size; sour->ch[1]->lsum = sour->ch[1]->rsum = sour->ch[1]->msum = sour->cover? 0: sour->ch[1]->size; sour->cover = -1; } } void rotate(NODE *sour, int flag) { NODE *f = sour->fa; push_down(f); push_down(sour); f->ch[!flag] = sour->ch[flag]; sour->ch[flag]->fa = f; sour->fa = f->fa; if(f->fa != NIL) f->fa->ch[f->fa->ch[1] == f] = sour; sour->ch[flag] = f; f->fa = sour; push_up(f); } void splay(NODE *sour, NODE *goal) { push_down(sour); while(sour->fa != goal) { if(sour->fa->fa == goal) rotate(sour, sour->fa->ch[0] == sour); else { NODE *f = sour->fa; int flag = (f->fa->ch[0] == f); if(f->ch[flag] == sour) rotate(sour, !flag); else rotate(f, flag); rotate(sour, flag); } } push_up(sour); if(goal == NIL) root = sour; } NODE *select(int r, NODE *sour) { push_down(sour); while(sour != NIL && r != sour->ch[0]->size+1) { if(r <= sour->ch[0]->size) sour = sour->ch[0]; else { r -= sour->ch[0]->size+1; sour = sour->ch[1]; } push_down(sour); } return sour; } NODE *find(int op, NODE *sour) { if(op > sour->msum) return NIL; push_down(sour); NODE *ret; while(sour != NIL) { if(op <= sour->ch[0]->msum) sour = sour->ch[0]; else if(sour->color != 1 && op <= sour->ch[0]->rsum+sour->ch[1]->lsum+1) { ret = select(sour->ch[0]->size-sour->ch[0]->rsum+1, sour); break; } else sour = sour->ch[1]; push_down(sour); } return ret; } NODE *search(const T1 &value) { NODE *sour = root; push_down(sour); while(sour != NIL && value != sour->key) { sour = sour->ch[value > sour->key]; push_down(sour); } return sour; } void build_tree(int l, int r, NODE *&sour, NODE *f) { if(l > r) return; int m = (l+r) >> 1; newnode(sour, f, m, 0); build_tree(l, m-1, sour->ch[0], sour); build_tree(m+1, r, sour->ch[1], sour); push_up(sour); } void updata(int ql, int qr, int op) { NODE *sour = select(ql, root); splay(sour, NIL); sour = select(qr+2, root); splay(sour, root); sour = root->ch[1]->ch[0]; sour->color = sour->cover = op; sour->lsum = sour->rsum = sour->msum = op? 0: sour->size; } int query(int op) { NODE *sour = select(1, root); splay(sour, NIL); sour = select(n+2, root); splay(sour, root); sour = find(op, root->ch[1]->ch[0]); if(sour == NIL) return 0; else return sour->key; } void debug() { printf("/****************************************/\n"); debug_(root, 0); printf("/****************************************/\n"); } void debug_(NODE *sour, int vec) { if(sour == NIL) return; debug_(sour->ch[0], vec+1); for(int i = 0; i < vec; ++i) printf(" "); printf("(%d, %d, %d, %d)\n", sour->key, sour->lsum, sour->rsum, sour->msum); debug_(sour->ch[1], vec+1); } }; SPLAY_TREE<int, int> spt; int main() { int m; int flag, op1, op2, ret; // freopen("d:\\out.txt", "w", stdout); while(~scanf("%d%d", &n, &m)) { spt.init(); for(int i = 0; i < m; ++i) { scanf("%d", &flag); if(flag == 1) { scanf("%d", &op1); ret = spt.query(op1); printf("%d\n", ret); if(ret != 0) spt.updata(ret, ret+op1-1, 1); } else { scanf("%d%d", &op1, &op2); spt.updata(op1, op1+op2-1, 0); } // spt.debug(); } } return 0; }