题目:
题解:
rotate写挂了。。。此题不用计算size哦
代码:
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <iostream>
#define N 40005
#define INF 2e9
using namespace std;
int f[N+5],ch[N+5][2],cnt[N+5],key[N+5],root,sz;
bool ff1,ff2;
int get(int x){return ch[f[x]][1]==x;}
void rotate(int x)
{
int old=f[x],oldf=f[old],which=get(x);
ch[old][which]=ch[x][which^1]; f[ch[x][which^1]]=old;
ch[x][which^1]=old; f[old]=x;
f[x]=oldf;
if (oldf) ch[oldf][ch[oldf][1]==old]=x;
}
void splay(int x)
{
for (int fa;fa=f[x];rotate(x))
if (f[fa])
rotate(get(x)==get(fa)?fa:x);
root=x;
}
int pre()
{
if (cnt[root]>1) return key[root];
int now=ch[root][0];
if (!now) return -INF;
while (ch[now][1]) now=ch[now][1];
return key[now];
}
int next()
{
if (cnt[root]>1) return key[root];
int now=ch[root][1];
if (!now) return INF;
while (ch[now][0]) now=ch[now][0];
return key[now];
}
void insert(int x)
{
if (root==0)
{
root=++sz; f[sz]=ch[sz][0]=ch[sz][1]=0; key[sz]=x;
}
int now=root,fa=0;
while (1) {
if (x==key[now]) {
cnt[now]++;
splay(now);
return;
}
fa=now;
now=ch[now][key[now]<x];
if(now==0) {
sz++;
f[sz]=fa;
ch[sz][0]=ch[sz][1]=0;
key[sz]=x;
cnt[sz]=1;
ch[fa][key[fa]<x]=sz;
splay(sz);
break;
}
}
}
int main()
{
int n,i,b,ans=0;
scanf("%d",&n);
for (i=1;i<=n;i++)
{
if (scanf("%d",&b)==EOF) b=0;
insert(b);
if (i==1)
{
ans+=b;continue;
}
int a1=pre(),a2=next();
ans+=min(abs(a1-b),abs(b-a2));
}
printf("%d",ans);
}
旋转操作与伸展树详解
本文介绍了一种使用伸展树(Splay Tree)的数据结构实现,通过旋转操作(rotate)来保持树的平衡,从而高效地进行查找、插入等操作。文中详细解释了伸展树的基本概念、旋转操作的具体实现,并提供了一个完整的C++代码示例,包括伸展树节点的定义、插入元素的方法、以及获取前驱和后继节点的函数。
553

被折叠的 条评论
为什么被折叠?



