您的位置:首页 > 其它

【Tyvj1185】【codevs1296】【BZOJ1588】营业额统计,Splay练习

2016-03-25 07:18 441 查看
传送门1

传送门2

传送门3

写在前面:身体不舒服,感觉有点差

思路:查询时先找是否有这个元素,没有的话再分别找前驱后继。

注意:BZOJ数据有错,详见讨论版

代码:

#include<bits/stdc++.h>
using namespace std;
int n,x,root,tot,p,q,ans,fuck;
struct os
{
int fa,occ,sz,ch[2],data;
}a[100000];
void ct(int now)
{
a[now].sz=a[now].occ+a[a[now].ch[0]].sz+a[a[now].ch[1]].sz;
}
void made(int x)
{
a[++tot].data=x;
a[tot].occ=a[tot].sz=1;
}
void rorate(int now,bool flag)
{
int pa=a[now].fa;
a[pa].ch[!flag]=a[now].ch[flag];
a[a[now].ch[flag]].fa=pa;
if (a[a[pa].fa].ch[0]==pa) a[a[pa].fa].ch[0]=now;
else a[a[pa].fa].ch[1]=now;
a[now].fa=a[pa].fa;
a[pa].fa=now;
a[now].ch[flag]=pa;
ct(pa);
ct(now);
}
void splay(int now,int goal)
{
int pa;
while (a[now].fa!=goal)
{
pa=a[now].fa;
if (a[pa].fa==goal)
{
if (a[pa].ch[0]==now) rorate(now,1);
else rorate(now,0);
}
else if (a[a[pa].fa].ch[0]==pa)
{
if (a[pa].ch[0]==now) rorate(pa,1);
else rorate(now,0);
rorate(now,1);
}
else
{
if (a[pa].ch[1]==now) rorate(pa,0);
else rorate(now,1);
rorate(now,0);
}
}
if (!goal) root=now;
}
void insert(int x)
{
if (!root) {made(x);root=tot;return;}
int now=root;
while (now)
{
a[now].sz++;
if (x==a[now].data){a[now].occ++;splay(now,0);return;}
else if (x<a[now].data)
{
if (!a[now].ch[0])
{
made(x);
a[now].ch[0]=tot;
a[tot].fa=now;
splay(tot,0);
return;
}
else now=a[now].ch[0];
}
else
{
if (!a[now].ch[1])
{
made(x);
a[now].ch[1]=tot;
a[tot].fa=now;
splay(tot,0);
return;
}
else now=a[now].ch[1];
}
}
}
int find(int x)
{
int now=root;
while (now)
{
if (a[now].data==x) return now;
if (a[now].data>x) now=a[now].ch[0];
else now=a[now].ch[1];
}
return 0;
}
int find_next_max(int x)
{
int now=root,ans=0;
while (now)
{
if (a[now].data>x)
ans=(!ans||a[ans].data>a[now].data)?now:ans,
now=a[now].ch[0];
else now=a[now].ch[1];
}
if (ans) splay(ans,0);
return ans;
}
int find_next_min(int x)
{
int now=root,ans=0;
while (now)
{
if (a[now].data<x)
ans=(!ans||a[ans].data<a[now].data)?now:ans,
now=a[now].ch[1];
else now=a[now].ch[0];
}
if (ans) splay(ans,0);
return ans;
}
main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
if (scanf("%d",&x)==EOF) x=0;
if (find(x)) {insert(x);continue;}
p=find_next_max(x);
q=find_next_min(x);
if (!p&&!q) ans+=x;
else if (!p) ans+=x-a[q].data;
else if (!q) ans+=a[p].data-x;
else ans+=(a[p].data-x>x-a[q].data)?x-a[q].data:a[p].data-x;
insert(x);
}
printf("%d",ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: