关于如何写splay

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于如何写splay相关的知识,希望对你有一定的参考价值。

这是bzoj1208 郁闷的出纳员

#include<iostream>
#define N 200000
#define abs(x) ((x) > 0? (x): -(x))
using namespace std;
int n;
int now, ans;
struct splay
{
int ch[2];
int fa, si;
int dt;
};
splay tr[N];
int root, tl;
int is_right(int t) {return (tr[tr[t].fa].ch[1] == t);}
void rotate(int t)
{
int k = is_right(t), b = tr[t].ch[!k], a = tr[t].fa, o = tr[a].fa;
tr[a].ch[k] = b; tr[t].ch[!k]=a; if (o) tr[o].ch[is_right(a)] = t; else root = t;
if (b) tr[b].fa = a; tr[a].fa = t; tr[t].fa = o;
tr[a].si = tr[tr[a].ch[0]].si + tr[tr[a].ch[1]].si + 1;
tr[t].si = tr[tr[t].ch[0]].si + tr[tr[t].ch[1]].si + 1;
}
void up(int t)
{
while ((root != t) && (root))
{
if (tr[t].fa == root) {rotate(t); break;}
int a = tr[t].fa;
if (is_right(t) == is_right(a)) rotate(a), rotate(t);
else rotate(t), rotate(t);
}
}
int ask_before(int d)
{
int q = 0;
for (int p = root; p; )
if (tr[p].dt <= d) {q = p; p = tr[p].ch[1];}
else p = tr[p].ch[0];
return q;
}
int ask_after(int d)
{
int q = 0;
for (int p = root; p; )
if (tr[p].dt >= d) {q = p; p = tr[p].ch[0];}
else p = tr[p].ch[1];
return q;
}
void insert(int d)
{
int p = 0;
tl++;
if (root)
{
for (p = root; tr[p].ch[d > tr[p].dt]; p = tr[p].ch[d > tr[p].dt]) tr[p].si++;
tr[p].ch[d > tr[p].dt] = tl;
}
else root = tl;
tr[tl].fa = p; tr[tl].si = 1; tr[tl].dt = d;
up(tl);
}
void dele(int t)
{
int pp = 0;
up(t);
if (tr[t].ch[0])
{
root = tr[t].ch[0]; tr[root].fa = 0;
for (pp = root; tr[pp].ch[1]; pp = tr[pp].ch[1]);
up(pp);
}
else if (tr[t].ch[1]) root = tr[t].ch[1];
else root = 0;
tr[pp].ch[1] = tr[t].ch[1]; tr[pp].si += tr[tr[t].ch[1]].si; tr[tr[t].ch[1]].fa = pp;
tr[t].ch[0] = 0; tr[t].ch[1] = 0; tr[t].dt = 0 ; tr[t].si = 0;
}
int main()
{
cin >> n;
for (int i=1; i<=n; ++i)
{
int a, b;
cin >> a >> b;
if (!root) now = a;
if (a == now)
{
insert(b);
}
else
{
int p1 = ask_before(b), p2 = ask_after(b);
if (!p1) ans += abs(tr[p2].dt - b), dele(p2);
else if (!p2) ans += abs(tr[p1].dt - b), dele(p1);
else if (abs(tr[p1].dt - b) <= abs(tr[p2].dt - b)) ans += abs(tr[p1].dt - b), dele(p1);
else ans += abs(tr[p2].dt - b), dele(p2);
}
ans %= 1000000;
}
cout << ans;
}

以上是关于关于如何写splay的主要内容,如果未能解决你的问题,请参考以下文章

splay的写法

算法详解splay的初步了解

UESTC2021暑假前集训(splay树)

模板Splay

bzoj2733: [HNOI2012]永无乡(splay+启发式合并/线段树合并)

bzoj2733 永无乡 splay树的启发式合并