開始以為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);elserotate(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];elseif(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;}elsesour = 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;elsereturn 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;}