您的位置:首页 > 其它

[HNOI2002]营业额统计(Splay tree 入门)

2015-11-15 10:23 363 查看

[HNOI2002]营业额统计

Description

营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。 Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析营业情况是一项相当复杂的工作。由于节假日,大减价或者是其他情况的时候,营业额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题。经济管理学上定义了一种最小波动值来衡量这种情况:
该天的最小波动值 当最小波动值越大时,就说明营业情况越不稳定。 而分析整个公司的从成立到现在营业情况是否稳定,只需要把每一天的最小波动值加起来就可以了。你的任务就是编写一个程序帮助Tiger来计算这一个值。 第一天的最小波动值为第一天的营业额。  输入输出要求

Input

第一行为正整数 ,表示该公司从成立一直到现在的天数,接下来的n行每行有一个整数(有可能有负数) ,表示第i天公司的营业额。

Output

输出文件仅有一个正整数,即Sigma(每天最小的波动值) 。结果小于2^31 。

Sample Input

6

5

1

2

5

4

6

Sample Output

12

HINT

结果说明:5+|1-5|+|2-1|+|5-5|+|4-5|+|6-5|=5+4+1+0+1+1=12

此题数据有问题,详见讨论版http://www.lydsy.com/JudgeOnline/wttl/wttl.php?pid=1588

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int Max=100005;
const int INF=0x3f3f3f3f;
struct SplayTree
{
int root;
int tot;
int parent[Max];
int value[Max];
int child[Max][2]; //左右孩子(0左1右)
//初始化
inline void Init()
{
root=0;
tot=0;
parent[0]=0;
child[0][0]=child[0][1]=0;
}
//新建一个结点
inline void NewNode(int &x,int fa,int key)
{
x=++tot;
parent[x]=fa;
value[x]=key;
child[x][0]=child[x][1]=0;
}

//旋转,kind为1是右旋,为0是左旋
inline void Rotate(int x,int kind)
{
int y=parent[x]; //父节点
int grandparent=parent[y]; //祖父结点
child[y][!kind]=child[x][kind]; //调整孩子结点
parent[child[x][kind]]=y;  //设置孩子结点新父节点
if(grandparent) //如果存在祖父结点
child[grandparent][child[grandparent][1]==y]=x;
else
root=x;  //x将成为root,更新root
parent[x]=grandparent; //设置x父节点
child[x][kind]=y;  //设置新的x结点的孩子
parent[y]=x;
}
//Splay调整,将结点x调整到goal下面
inline void Splay(int x,int goal)
{
while(parent[x]!=goal)
{
if(parent[parent[x]]==goal) //这种情况只需一次旋转
Rotate(x, child[parent[x]][0]==x);
else
{
int y=parent[x];
int kind=child[parent[y]][0]==y;
if(child[y][kind]==x) //祖父与孙子结点异侧
{
Rotate(x, !kind);
Rotate(x, kind);
}
else   //祖父与孙子结点同侧
{
Rotate(y, kind);
Rotate(x, kind);
}
}
}
}
inline int Insert(int key)
{
if(root==0)
{
NewNode(root, 0, key);
return 1;
}
int x=root;
while(child[x][value[x]<key] ||value[x]==key )
{

//不重复插入
if(value[x]==key)
{
Splay(x, 0); //调整
return 0;
}
x=child[x][value[x]<key];
}
//建立新结点
NewNode(child[x][value[x]<key], x, key);
//调整
Splay(child[x][value[x]<key], 0);
return 1;
}
//找其和前驱(kind=1)或后继(kind=0)差
inline int get_value(int x,int kind)
{
int temp=child[x][!kind];
if(temp==0)
return INF;
while(child[temp][kind])
temp=child[temp][kind];
return abs(value[x]-value[temp]);
}
};
int main()
{
int n,key;
SplayTree Splay;
while (scanf("%d",&n)!=EOF)
{
int ans=0;
Splay.Init();
for (int i=0; i<n; i++)
{
if(scanf("%d",&key)==EOF)
key=0;
if (i==0)
{
ans+=key;
Splay.Insert(key);
continue;
}
if (Splay.Insert(key)==1)
ans+=min(Splay.get_value(Splay.root, 0),Splay.get_value(Splay.root, 1));
}
printf("%d\n",ans);
}
return 0;
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: