您的位置:首页 > 其它

【codevs1285】【BZOJ1208】宠物收养所,splay练习

2016-03-11 20:15 363 查看
传送门1

传送门2

写在前面:我自己也会被写进机房大事记……

思路:很裸的splay练习,只涉及查前驱后继和删除操作,加一个标记记录现在是宠物多还是人多即可

注意:

1.查询和调用前驱后继时可能两者同时存在,记得判断一下

2.不知道为什么用bool型做树的标记时总是自己莫名改值,害我调了好久

代码:

#include<bits/stdc++.h>
#define mod 1000000
int n,x,tot,root,ans;
int hand,flag;
struct os
{
int data,fa,left,right,sz;
}a[100010];
int in()
{
int f=1,t=0;
char ch=getchar();
while (ch>'9'||ch<'0')
{
if (ch=='-') f=-1;
ch=getchar();
}
while (ch>='0'&&ch<='9') t=t*10+ch-'0',ch=getchar();
return f*t;
}
void made(int x)
{
a[++tot].data=x;
a[tot].sz=1;
}
void ct(int now)
{
a[now].sz=a[now].left+a[now].right+1;
}
void rorate(int now,bool flag)
{
int pa=a[now].fa;
if (flag)
{
a[pa].left=a[now].right;
if (a[now].right)a[a[now].right].fa=pa;
if (a[pa].fa)
{
if (a[a[pa].fa].left==pa) a[a[pa].fa].left=now;
else a[a[pa].fa].right=now;
}
a[now].fa=a[pa].fa;
a[pa].fa=now;
a[now].right=pa;
}
else
{
a[pa].right=a[now].left;
if (a[now].left)a[a[now].left].fa=pa;
if (a[pa].fa)
{
if (a[a[pa].fa].left==pa) a[a[pa].fa].left=now;
else a[a[pa].fa].right=now;
}
a[now].fa=a[pa].fa;
a[pa].fa=now;
a[now].left=pa;
}
ct(pa);
ct(now);
}
void splay(int x,int goal)
{
int y;
while (a[x].fa!=goal)
{
y=a[x].fa;
if (a[y].fa==goal)
{
if (a[y].left==x) rorate(x,1);
else rorate(x,0);
}
else if (y==a[a[y].fa].left)
{
if (a[y].left==x) rorate(y,1);
else rorate(x,0);
rorate(x,1);
}
else
{
if (a[y].right==x) rorate(y,0);
else rorate(x,1);
rorate(x,0);
}
}
if (!goal) root=x;
}
void insert(int x)
{
made(x);a[tot].data=x;
if (!root) {root=tot;return;}
int now=root;
while (now)
{
if (x<a[now].data)
{
if (!a[now].left) {a[now].left=tot;a[tot].fa=now;break;}
else now=a[now].left;
}
else
{
if (!a[now].right) {a[now].right=tot;a[tot].fa=now;break;}
else now=a[now].right;
}
}
splay(tot,0);
}
int find(int x)
{
int now=root;
while (now)
{
if (a[now].data==x) return now;
else if (a[now].data>x) now=a[now].left;
else now=a[now].right;
}
return 0;
}
int find_max(int now)
{
if (!now) return 0;
while (now)
{
if (a[now].right) now=a[now].right;
else return now;
}
}
bool del(int now)
{
splay(now,0);
if (!a[now].left&&!a[now].right){root=0;return 1;}
else if (!a[now].left)
{
a[a[now].right].fa=0;
root=a[now].right;
}
else if (!a[now].right)
{
a[a[now].left].fa=0;
root=a[now].left;
}
else
{
int child=find_max(a[now].left);
splay(child,root);
root=child;
a[child].right=a[now].right;
a[a[now].right].fa=child;
a[child].fa=0;
ct(child);
}
return 1;
}
int find_next_max(int x)
{
int now=root,k=0;
while (now)
{
if (a[now].data>x)
k=(a[k].data>a[now].data||!k)?now:k,
now=a[now].left;
else now=a[now].right;
}
if (k) splay(k,0);
return k;
}
int find_next_min(int x)
{
int now=root,k=0;
while (now)
{
if (a[now].data<x)
k=(a[k].data<a[now].data||!k)?now:k,
now=a[now].right;
else now=a[now].left;
}
if (k) splay(k,0);
return k;
}
main()
{
n=in();
for (int i=1;i<=n;i++)
{
scanf("%d%d",&hand,&x);
if (!root) flag=hand;
if (flag==hand) insert(x);
else
{
int p,p1=find_next_min(x),p2=find_next_max(x);
if (p1&&(x-a[p1].data<=a[p2].data-x||!p2)) p=p1;
else p=p2;
ans=(ans+abs(a[p].data-x))%mod;
del(p);
}
}
printf("%d",ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: