[知识点]平衡树之Splay

平衡树 之
Splay
1、前言
2、概念
3、Let's Splay
4、应用
代码:
-----------------------------------------------------------------------------------------------------------------
#include cstdio
#include cstring
#include algorithm
#include queue
#include cstring
#include algorithm
#include queue
#define MAXN
500005
#define INF 1<<30
using namespace std;
#define INF 1<<30
using namespace std;
struct Node
{
int son[2],l,r,m,k,t1,t2,s,sum,fa;
};
{
};
Node
tree[MAXN];
int
m,n,root,a[MAXN];
char now[10];
queue Q;
char now[10];
queue Q;
void plus1(int
now,int val)
{
if (!now) return;
tree[now].k=val,tree[now].t1=1,tree[now].sum=tree[now].k*tree[now].s;
if
(tree[now].k>0)
tree[now].l=tree[now].r=tree[now].m=tree[now].sum;
else
tree[now].l=tree[now].r=tree[now].m=tree[now].k;
}
{
}
void plus2(int
now)
{
if (!now) return;
swap(tree[now].son[0],tree[now].son[1]),tree[now].t2^=1;
swap(tree[now].l,tree[now].r);
}
{
}
void push(int
now)
{
if (!now) return;
if
(tree[now].t1)
plus1(tree[now].son[0],tree[now].k),plus1(tree[now].son[1],tree[now].k),tree[now].t1=0;
if
(tree[now].t2)
plus2(tree[now].son[0]),plus2(tree[now].son[1]),tree[now].t2=0;
}
{
}
void update(int
now)
{
if (!now) return;
push(now);
int
lson=tree[now].son[0],rson=tree[now].son[1];
tree[now].s=tree[lson].s+tree[rson].s+1;
tree[now].sum=tree[lson].sum+tree[rson].sum+tree[now].k;
tree[now].l=max(tree[lson].l,tree[lson].sum+tree[now].k+max(tree[rson].l,0));
tree[now].r=max(tree[rson].r,tree[rson].sum+tree[now].k+max(tree[lson].r,0));
tree[now].m=max(max(tree[lson].m,tree[rson].m),tree[now].k+max(tree[lson].r,0)+max(tree[rson].l,0));
}
{
}
void rotate(int
now)
{
int
fa=tree[now].fa,gfa=tree[fa].fa,q=(tree[fa].son[1]==now),son=tree[now].son[q^1];
if
(gfa)
tree[now].fa=gfa,tree[gfa].son[tree[gfa].son[1]==fa]=now;
else
tree[now].fa=0,root=now;
tree[fa].son[q]=son;
if (son) tree[son].fa=fa;
tree[fa].fa=now,tree[now].son[q^1]=fa;
update(fa),update(now);
//让我来翻译一下这段话:
//新建变量:我的爸爸,我爸爸的爸爸,“我是我爸的右儿子”判断,我的左(右)儿子;
//如果我有爷爷,那么我的爸爸是我的爷爷,我的爷爷的儿子是我,左还是右取决于我爸爸是我爷爷的左还是右儿子;
//如果我没爷爷,那么我爸爸也没有了,我就是你们的祖宗
//我爸爸的儿子是我的儿子;如果我有儿子,那么我儿子的爸爸是我的爸爸
//我爸爸的爸爸是我,我的左(右)儿子是我爸爸。
{
//
//
//
//
//
//
}
void splay(int
now)
{
int k=0;
for
(int x=now;x;x=tree[x].fa) { k++; a[k]=x; }
for
(int i=k;i>=1;i--) push(a[i]);
while
(tree[now].fa) rotate(now);
}
{
}
void build(int
now,int l,int r)
{
int mid=(l+r)>>1;
if
(l《mid)
tree[now].son[0]=Q.front(),Q.pop(),build(tree[now].son[0],l,mid-1),tree[tree[now].son[0]].fa=now;
scanf("%d",&tree[now].k);
if
(mid《r)
tree[now].son[1]=Q.front(),Q.pop(),build(tree[now].son[1],mid+1,r),tree[tree[now].son[1]].fa=now;
update(now);
}
{
}
int rank(int q)
{
int now=root;
while
(now)
{
push(now);
if
(tree[tree[now].son[0]].s+1==q) return now;
if
(tree[tree[now].son[0]].s>=q) now=tree[now].son[0];
else
q-=tree[tree[now].son[0]].s+1,now=tree[now].son[1];
}
return
0;
}
{
}
void ins()
{
int
pos,tot,l,r,root; scanf("%d %d",&pos,&tot);
l=rank(pos),r=rank(pos+1);
splay(l),splay(r);
root=Q.front(),Q.pop(),build(root,1,tot);
if
(l) tree[l].son[1]=root,tree[root].fa=l;
else
tree[r].son[0]=root,tree[root].fa=r;
update(l),update(r);
}
{
}
void DFS(int
now)
{
if (tree[now].son[0]) DFS(tree[now].son[0]);
if
(tree[now].son[1]) DFS(tree[now].son[1]);
Q.push(now),memset(tree+now,0,sizeof(tree[now]));
}
{
}
void del()
{
int pos,tot,l,r; scanf("%d %d",&pos,&tot);
l=rank(pos-1),r=rank(pos+tot);
splay(l),splay(r);
if
(l) DFS(tree[l].son[1]),tree[l].son[1]=0;
else
DFS(tree[r].son[0]),tree[r].son[0]=0;
update(l),update(r);
}
{
}
void makeSame()
{
int pos,tot,c,l,r; scanf("%d %d
%d",&pos,&tot,&c);
l=rank(pos-1),r=rank(pos+tot);
splay(l),splay(r);
if
(l) plus1(tree[l].son[1],c); else plus1(tree[r].son[0],c);
update(l),update(r);
}
{
}
void reverse()
{
int
pos,tot,l,r; scanf("%d %d",&pos,&tot);
l=rank(pos-1),r=rank(pos+tot);
splay(l),splay(r);
if
(l) plus2(tree[l].son[1]); else if (r) plus2(tree[r].son[0]); else
plus2(root);
updat e(l),update(r);
}
{
}
int getSum()
{
int pos,tot,l,r; scanf("%d %d",&pos,&tot);
l=rank(pos-1),r=rank(pos+tot);
splay(l),splay(r);
if
(l) return tree[tree[l].son[1]].sum;
{
}
int maxSum() { return
tree[root].m; }
void init()
{
freopen("1500.in","r",stdin);
freopen("1500.out","w",stdout);
scanf("%d
%d",&n,&m);
for
(int i=1;i<=MAXN;i++) Q.push(i);
tree[0].l=tree[0].r=tree[0].m=-INF;
root=Q.front(),Q.pop(),build(root,1,n);
}
{
}
int main()
{
init();
for
(int i=1;i<=m;i++)
{
scanf("%s",&now);
if
(now[0]=='I') ins();
else
if (now[0]=='D') del();
else
if (now[2]=='K') makeSame();
else
if (now[0]=='R') reverse();
else
if (now[0]=='G') printf("%d\n",getSum());
else
printf("%d\n",maxSum());
}
return 0;
}
{
}
-----------------------------------------------------------------------------------------------------------------
前一篇:[题解]星球大战
后一篇:[总结+题解]NOI2015