splay
从 Trac 迁移的文章
这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。
原文章内容如下:
=== 版本一 ===
{{{
#include <cstdio>
#include <iostream>
#define debug(x) cout<<#x<<" = "<<x<<endl
#define KEY (bt->o[0]->o[1])
using namespace std;
typedef long long LL;
const int maxn=100001+2;
//要在最前面和最后面分别插入空节点,以方便后续操作
//区间操作时要先splay左端点,再splay右端点,然后直接对KEY进行操作就行了
struct bst{
bst *o[2],*f;
bool root;
int size;
LL w,sum,mark;
}tnull,*null=&tnull,tbt[maxn]; int tpo;
bst *bt;
bst *newnode();
void update(bst *t);
void pushdown(bst *t,int d);
void pushdown(bst *t);
void rot(bst *t);
void splay(bst *t)//还要改改...
{
while (!t->root) rot(t);
update(t);
bt=t;
}
bst *find(int k)
{
bst *t=bt;
while (t->o[0]->size+1!=k)
{
if (k>t->size) return 0;
if (k<=t->o[0]->size) t=t->o[0];
else k-=t->o[0]->size+1,t=t->o[1];
}
return t;
}
bst *newnode()
{
bst *p=&tbt[tpo++];
p->o[0]=p->o[1]=p->f=null;
p->root=0;
p->size=1;
p->w=p->sum=0;
return p;
}
void update(bst *t)
{
t->size=t->o[0]->size+t->o[1]->size+1;
t->sum=t->o[0]->sum+t->o[1]->sum+t->w;
}
void pushdown(bst *t,int d)
{
t->o[d]->sum+=t->mark*t->o[d]->size;
t->o[d]->w+=t->mark;
t->o[d]->mark+=t->mark;
}
void pushdown(bst *t)
{
if (!t->mark) return;
if (t->o[0]!=null) pushdown(t,0);
if (t->o[1]!=null) pushdown(t,1);
t->mark=0;
}
void rot(bst *t)
{
bst *p=t->f;
int d=(p->o[0]!=t);
pushdown(p); pushdown(t);
p->o[d]=t->o[!d]; t->o[!d]->f=p;
t->f=p->f;
if (p->f!=null)
if (p->f->o[0]==p) p->f->o[0]=t;
else p->f->o[1]=t;
p->f=t; t->o[!d]=p;
t->root=p->root; p->root=0;
update(p);
}
}}}
版本一
#include <cstdio>
#include <iostream>
#define debug(x) cout<<#x<<" = "<<x<<endl
#define KEY (bt->o[0]->o[1])
using namespace std;
typedef long long LL;
const int maxn=100001+2;
//要在最前面和最后面分别插入空节点,以方便后续操作
//区间操作时要先splay左端点,再splay右端点,然后直接对KEY进行操作就行了
struct bst{
bst *o[2],*f;
bool root;
int size;
LL w,sum,mark;
}tnull,*null=&tnull,tbt[maxn]; int tpo;
bst *bt;
bst *newnode();
void update(bst *t);
void pushdown(bst *t,int d);
void pushdown(bst *t);
void rot(bst *t);
void splay(bst *t)//还要改改...
{
while (!t->root) rot(t);
update(t);
bt=t;
}
bst *find(int k)
{
bst *t=bt;
while (t->o[0]->size+1!=k)
{
if (k>t->size) return 0;
if (k<=t->o[0]->size) t=t->o[0];
else k-=t->o[0]->size+1,t=t->o[1];
}
return t;
}
bst *newnode()
{
bst *p=&tbt[tpo++];
p->o[0]=p->o[1]=p->f=null;
p->root=0;
p->size=1;
p->w=p->sum=0;
return p;
}
void update(bst *t)
{
t->size=t->o[0]->size+t->o[1]->size+1;
t->sum=t->o[0]->sum+t->o[1]->sum+t->w;
}
void pushdown(bst *t,int d)
{
t->o[d]->sum+=t->mark*t->o[d]->size;
t->o[d]->w+=t->mark;
t->o[d]->mark+=t->mark;
}
void pushdown(bst *t)
{
if (!t->mark) return;
if (t->o[0]!=null) pushdown(t,0);
if (t->o[1]!=null) pushdown(t,1);
t->mark=0;
}
void rot(bst *t)
{
bst *p=t->f;
int d=(p->o[0]!=t);
pushdown(p); pushdown(t);
p->o[d]=t->o[!d]; t->o[!d]->f=p;
t->f=p->f;
if (p->f!=null)
if (p->f->o[0]==p) p->f->o[0]=t;
else p->f->o[1]=t;
p->f=t; t->o[!d]=p;
t->root=p->root; p->root=0;
update(p);
}