开始以为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;
}