您的位置:首页 > 其它

[HNOI 2004]宠物收养所

2014-01-21 13:51 489 查看
同样是HNOI的一道水题,非常鄙视那些用set的人……

其实这是一道平衡树维护的题,很显而易见要维护两颗平衡树(好吧最开始做题目居然只建立了一棵SplayTree,然后WA到想哭……),而且两棵树中必然有一颗是空的,易证。

无非就是注意几个特别的操作,详见代码。#include <cstdio>
#define abs(x) (((x)>=0)? (x):-(x))
#define MaxN 80010
using namespace std;
int ans,n;
struct splaytree
{
int a[MaxN],l[MaxN],r[MaxN];
int t,tot;
inline void zig(int &x)
{
int lc=l[x];
l[x]=r[lc];
r[lc]=x;
x=lc;
}
inline void zag(int &x)
{
int rc=r[x];
r[x]=l[rc];
l[rc]=x;
x=rc;
}
inline void splay(int &t,int x)
{
if(!t) return;
int pl=0,pr=0;
for(;;)
{
if(x==a[t]) break;
if(x<a[t]&&!l[t]) break;
if(x>a[t]&&!r[t]) break;
if(x<a[t])
{
if(x<a[l[t]]&&l[l[t]])
zig(t);
l[pr]=t,pr=t,t=l[t];
}
else
{
if(x>a[r[t]]&&r[r[t]])
zag(t);
r[pl]=t,pl=t,t=r[t];
}
}
l[pr]=r[t];
r[pl]=l[t];
l[t]=r[0];
r[t]=l[0];
l[0]=r[0]=0;
}
inline void insert(const int &x)
{
a[++tot]=x;
if(!t)
{
t=tot;
return;
}
splay(t,x);
if(x<a[t])
l[tot]=l[t],
l[t]=tot;
else
r[tot]=r[t],
r[t]=tot;
}
inline void suit(const int &x)
{
if(!t) return;
splay(t,x);
splay(l[t],a[t]);
splay(r[t],a[t]);
int pl=abs(a[l[t]]-x),pm=abs(a[t]-x),pr=abs(a[r[t]]-x);
if(x<a[t]&&pl<=pm&&l[t])
{
ans+=pl;
ans%=1000000;
l[t]=l[l[t]];
}
else if(x>a[t]&&pr<pm&&r[t])
{
ans+=pr;
ans%=1000000;
r[t]=r[r[t]];
}
else
{
ans+=pm;
ans%=1000000;
if(l[t])
r[l[t]]=r[t],
t=l[t];
else if(r[t])
l[r[t]]=l[t],
t=r[t];
else t=0;
}
}
}SP[2];
int main()
{
freopen("in","r",stdin);
freopen("out","w",stdout);
int x,y;
scanf("%d",&n);
while(n--)
{
scanf("%d%d",&x,&y);
if(SP[x].t)
SP[x].suit(y);
else
SP[!x].insert(y);
}
printf("%d",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  splay 平衡二叉树