您的位置:首页 > 其它

BZOJ 1208

2014-03-06 18:24 447 查看
我表示只用一棵 Splay 。

因为题目里明确说明了“同一时间呆在收养所中的,要么全是宠物,要么全是领养者”。

每个节点存一个 kind 值。

找前驱找后继删节点删根,不说了。。。

删根的时候没判有没有儿子WA了几次。。。

丑陋的代码贴出。。。

#include <iostream>
#include <cstdio>
#include <cstring>

const int INF=1<<29;
const int M=1000000;
const int N=80100;
int ch
[2],key
,kind
,pre
;
int n,i,a,b,tot,rt,ans;

void newnode(int x,int k,int fa)
{
key[++tot]=x;
kind[tot]=k;
pre[tot]=fa;
ch[fa][x>=key[fa]]=tot;
ch[tot][0]=ch[tot][1]=0;
}

void rotate(int x,int k)
{
int y=pre[x];
ch[y][!k]=ch[x][k];
pre[ch[x][k]]=y;
if (pre[y]) ch[pre[y]][ch[pre[y]][1]==y]=x;
pre[x]=pre[y];
ch[x][k]=y;
pre[y]=x;
}

void splay(int x,int goal)
{
while (pre[x]!=goal)
{
int y=pre[x];
if (pre[y]==goal) rotate(x,ch[y][0]==x);
else
{
int k=ch[pre[y]][0]==y;
if (ch[y][k]==x)
{
rotate(x,!k);
rotate(x,k);
}
else
{
rotate(y,k);
rotate(x,k);
}
}
}
if (!goal) rt=x;
}

void ins(int k,int x)
{
if (!rt)
{
newnode(x,k,0);
rt=tot;
return;
}
int r=rt;
while (ch[r][x>=key[r]]) r=ch[r][x>=key[r]];
int f=kind[r]^k;
newnode(x,k,r);
splay(tot,0);
if (f)
{
int tl=ch[rt][0];
int tr=ch[rt][1];
if (tl) while (ch[tl][1]) tl=ch[tl][1];
if (tr) while (ch[0]) tr=ch[0];
int t1=tl?key[rt]-key[tl]:INF;
int t2=tr?key-key[rt]:INF;
if (t1>t2)
{
ans=(ans+t2)%M;
splay(tr,rt);
ch[rt][1]=ch[1];
if (ch[1]) pre[ch[1]]=rt;
pre=key=ch[0]=ch[1]=0;
if (ch[rt][0]==0&&ch[rt][1]==0)
{
rt=0;
return;
}
int tmp=rt;
if (ch[tmp][0]==0)
{
rt=ch[tmp][1];
pre[rt]=pre[tmp]=key[tmp]=ch[tmp][0]=ch[tmp][1]=0;
return;
}
r=ch[tmp][1];
rt=ch[tmp][0];
pre[rt]=pre[tmp]=key[tmp]=ch[tmp][0]=ch[tmp][1]=0;
if (tl) ch[tl][1]=r;
if (r) pre[r]=tl;
if (tl) splay(tl,0);
}
else
{
ans=(ans+t1)%M;
splay(tl,rt);
ch[rt][0]=ch[tl][0];
if (ch[tl][0]) pre[ch[tl][0]]=rt;
key[tl]=ch[tl][0]=ch[tl][1]=0;
if (ch[rt][0]==0&&ch[rt][1]==0)
{
rt=0;
return;
}
int tmp=rt;
if (ch[tmp][1]==0)
{
rt=ch[tmp][0];
pre[rt]=pre[tmp]=key[tmp]=ch[tmp][0]=ch[tmp][1]=0;
return;
}
r=ch[tmp][0];
rt=ch[tmp][1];
pre[rt]=pre[tmp]=key[tmp]=ch[tmp][0]=ch[tmp][1]=0;
if (tr) ch[0]=r;
if (r) pre[r]=tr;
if (tr) splay(tr,0);
}
}
}

int main()
{
scanf("%d",&n);
for (i=1;i<=n;i++)
{
scanf("%d%d",&a,&b);
ins(a,b);
}
printf("%d\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  BZOJ Splay