您的位置:首页 > 其它

BZOJ 1588 [HNOI2002]营业额统计

2016-08-20 15:52 429 查看
splay。

模仿别人的代码打的,加了一些注释

我很好奇排名第一的0s用了什么神奇的数结- -

#include<cstdio>
#include<cmath>
#include<algorithm>
#define N 200005
using namespace std;
const int INF = 1<<29;
struct SplayTree
{
int son
[2], fa
, siz
, cnt
, val
, root, tot;
void up(int x)
{
siz[x]=siz[son[x][0]]+siz[son[x][1]]+cnt[x];
}
void rotate(int x, int flag)//flag 0左旋 1右旋
{
int y=fa[x];
//分步处理,都是两行,一个改fa一个改son
//1.处理x的儿子
son[y][flag^1]=son[x][flag];
fa[son[x][flag]]=y;
//2.处理y的父亲
fa[x]=fa[y];
if(fa[y])son[fa[y]][son[fa[y]][1]==y]=x;
//3.处理x和y
fa[y]=x;
son[x][flag]=y;
up(y);
}
void splay(int x, int goal)//将x旋到goal之下,goal=0表示x转为根
{
while(fa[x]!=goal)
{
if(fa[fa[x]]==goal)//单旋
rotate(x,son[fa[x]][0]==x);
else
{
int fax=fa[x], faxx=fa[fax], flag=(son[faxx][0]==fax);
if(son[x][flag]==x)//双左右旋,双右左旋
{
rotate(x,!flag);
rotate(x,flag);
}
else//双左左旋,双右右旋
{
rotate(fax,flag); //父亲单旋,以降低层数
rotate(x,flag);
}
}
}
up(x);
if(goal==0)
root=x;
}
void add_node(int v, int fat)
{
val[++tot]=v;
son[tot][1]=son[tot][0]=0;
fa[tot]=fat;
son[fat][val[fat]<v]=tot;
cnt[tot]=siz[tot]=1;
}
void init()
{
tot=0;
root=1;
add_node(INF,0);//实际上是一号节点
add_node(-1*INF,1); //实际上是二号节点
//加入最值保证查找不出错
siz[1]=1;
}
void inser(int pre, int fat, int v)
{
if(!pre)
{
add_node(v,fat);
splay(tot,0);
return;
}
if(val[pre]==v)
{
cnt[pre]++;
up(pre);
splay(pre,0);
return;
}
if(v>val[pre])inser(son[pre][1],pre,v);
else inser(son[pre][0],pre,v);
up(pre);
}
void find_max(int &x, int pre, int v)
{
if(!pre)return;
if(v<=val[pre])
{
x=val[pre];
find_max(x,son[pre][0],v);
}
else
find_max(x,son[pre][1],v);
}
void find_min(int &x, int pre, int v)
{
if(!pre)return;
if(v>val[pre])
{
x=val[pre];
find_min(x,son[pre][1],v);
}
else
find_min(x,son[pre][0],v);
}
}st;
int main()
{
int n, a;
st.init();
scanf("%d",&n);
scanf("%d",&a);
st.inser(st.root,0,a);
int ans=a;
for(int i = 1; i < n; i++)
{
int pre1, pre2, now;
scanf("%d",&a);
st.find_max(pre1,st.root,a);
st.find_min(pre2,st.root,a);
now=min(abs(pre2-a),abs(pre1-a));
ans+=now;
st.inser(st.root,0,a);
}
printf("%d\n",ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: