平衡树splay
防止以后复习时忘掉
#include<bits/stdc++.h>
using namespace std;
struct Tree
{
int ch[2], fa, val, size;
} tree[40001];
int n, X, root;
int tot, lef_root, rig_root;
long long ans;
bool check(int now)
{
return tree[tree[now].fa].ch[1] == now;//左孩子表示为0,右孩子表示为1
}
void rotate(int now)
{
int father = tree[now].fa;
int grand = tree[father].fa;
int k=check(now);
int son = tree[now].ch[k^1];//相反
//孩子连接到爷爷,父亲原来为左孩子则孩子为左孩子
tree[now].fa=grand,tree[grand].ch[check(father)]=now;
//前驱后继方向于孩子相反
tree[son].fa=father,tree[father].ch[k]=son;
tree[father].fa=now,tree[now].ch[k^1]=father;
}
void splay(int x, int target)
{
while (tree[x].fa != target)
{
if (tree[tree[x].fa].fa != target)
{
if(check(x)==check(tree[x].fa))
rotate(tree[x].fa);
else
rotate(x);
}
rotate(x);
}
if (!target)
root = x;
}
int find(int x)
{
int now = root;
while (now)
{
if (x == tree[now].val)
break;
if (x >= tree[now].val)
now = tree[now].ch[1];
else
now = tree[now].ch[0];
}
if (now != root)
splay(now, 0);
return now;
}
void insert(int x)
{
int now = root, last = 0;
while (now)
{
last = now;
tree[now].size++;
if (x < tree[now].val)
now = tree[now].ch[0];
else
now = tree[now].ch[1];
}
tot++;//新加一个节点
tree[tot].fa = last;
tree[tot].val = x;
tree[tot].size = 1;
if (x < tree[last].val)
tree[last].ch[0] = tot;
else
tree[last].ch[1] = tot;
splay(tot, 0);
}
void join(int small, int big)
{
tree[small].fa = tree[big].fa = 0;
int new_root = small;
while (tree[new_root].ch[1])//找到左子树中最大的
new_root = tree[new_root].ch[1];
splay(new_root, 0);
tree[new_root].ch[1] = big;
tree[big].fa = new_root;
}
void delete_(int x)
{
splay(x, 0);//删掉自己=把左子树+右子树
if (!tree[x].ch[0] && tree[x].ch[1])
tree[tree[x].ch[1]].fa = 0;
else if (tree[x].ch[0] && !tree[x].ch[1])
tree[tree[x].ch[0]].fa = 0;
else
join(tree[x].ch[0], tree[x].ch[1]);
tree[x].ch[0] = tree[x].ch[1] = 0;
}
int get_rank(int x)//得到排名
{
int now = find(x);
return tree[tree[now].ch[0]].size + 1;//左边孩子都小于我,所以排名为左子树节点数量+1
}
void spilt(int x)//分开
{
int no_root = find(x);//find后x为根节点
lef_root = tree[no_root].ch[0];//分开
rig_root = tree[no_root].ch[1];
tree[no_root].ch[0] = tree[no_root].ch[1] = 0;
}
int pre(int x)
{
int now = root;//此时x为根节点
now = tree[now].ch[0];
if (!now)
return -1;
while (tree[now].ch[1])//左子树最右边的点
{
now = tree[now].ch[1];
}
return tree[now].val;
}
int nxt(int x)
{
int now = root;//此时x为根节点
now = tree[now].ch[1];
if (!now)
return -1;
while (tree[now].ch[0])
{
now = tree[now].ch[0];//右子树最左边的点
}
return tree[now].val;
}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf("%d", &X);
insert(X);
if (i == 1)
ans += 1ll * X;
else
{
int XX = pre(X), YY = nxt(X);
if (XX == -1)
ans += YY - tree[root].val;
else if (YY == -1)
ans += tree[root].val - XX;
else
ans += min(tree[root].val - XX, YY - tree[root].val);
}
}
printf("%lld", ans);
return 0;
}
本文来自博客园,作者:流氓兔LMT,转载请注明原文链接:https://www.cnblogs.com/-include-lmt/p/18897292

浙公网安备 33010602011771号