HNOI2002 营业额统计 [Splay]

时间:2023-03-09 07:25:24
HNOI2002 营业额统计 [Splay]

题目描述

Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。

Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析营业情况是一项相当复杂的工作。由于节假日,大减价或者是其他情况的时候,营业额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题。经济管理学上定义了一种最小波动值来衡量这种情况:

当最小波动值越大时,就说明营业情况越不稳定。

而分析整个公司的从成立到现在营业情况是否稳定,只需要把每一天的最小波动值加起来就可以了。你的任务就是编写一个程序帮助Tiger来计算这一个值。

第一天的最小波动值为第一天的营业额。

该天的最小波动值=min{|该天以前某一天的营业额-该天营业额|}。

输入输出格式

输入格式:

输入由文件’turnover.in’读入。

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

输出格式:

HNOI2002 营业额统计 [Splay]

输入输出样例

输入样例#1:

6

5

1

2

5

4

6

输出样例#1:

12

说明

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

题解

splay裸题,每次在插入之前找到之前已经插入的比它大或比它小的第一个值,绝对值之后取个最小值

Code

#include<bits/stdc++.h>
#define in(i) (i=read())
using namespace std;
typedef long long lol;
const double delta=0.98;
const lol inf=2147483647; lol read() {
lol ans=0,f=1; char i=getchar();
while(i<'0' || i>'9') {if(i=='-') f=-1; i=getchar();}
while(i>='0' && i<='9') {ans=(ans<<1)+(ans<<3)+i-'0'; i=getchar();}
return ans*f;
}
lol Min(lol a,lol b) {
return (a>b)?(b):(a);
}
lol n,ans,tot,root;
struct node {
lol val,cnt,size,ch[2],ff;
}t[33000];
void pushup(lol x) {
t[x].size=t[t[x].ch[0]].size+t[t[x].ch[1]].size+t[x].cnt;
}
void rorate(lol x) {
lol y=t[x].ff,z=t[y].ff;
lol k=(t[y].ch[1]==x);
t[z].ch[t[z].ch[1]==y]=x; t[x].ff=z;
t[y].ch[k]=t[x].ch[k^1]; t[t[x].ch[k^1]].ff=y;
t[x].ch[k^1]=y; t[y].ff=x;
pushup(y); pushup(x);
}
void splay(lol x,lol goal) {
while(t[x].ff!=goal) {
lol y=t[x].ff,z=t[y].ff;
if(z!=goal) (t[z].ch[1]==y)^(t[y].ch[1]==x)?rorate(x):rorate(y);
rorate(x);
}
if(!goal) root=x;
}
inline void find(lol x) {
lol u=root;
if(!u) return;
while(t[u].ch[x>t[u].val] && x!=t[u].val) u=t[u].ch[x>t[u].val];
splay(u,0);
}
inline void insert(lol x) {
lol u=root,ff=0;
while(u && t[u].val!=x) {
ff=u;
u=t[u].ch[x>t[u].val];
}
if(u) t[u].cnt++;
else {
u=++tot;
if(ff) t[ff].ch[x>t[ff].val]=u;
t[u].ch[0]=t[u].ch[1]=0;
t[u].cnt=t[u].size=1;
t[u].val=x; t[u].ff=ff;
}
splay(u,0);
}
inline lol Next(lol x,lol f) {
find(x);
lol u=root;
if(t[u].val>=x && f) return u;
if(t[u].val<=x && !f) return u;
u=t[u].ch[f];
while(t[u].ch[f^1]) u=t[u].ch[f^1];
return u;
}
inline void Del(lol x) {
lol last=Next(x,0),next=Next(x,1);
splay(last,0); splay(next,last);
lol del=t[next].ch[0];
if(t[del].cnt>1) {
t[del].cnt--;
splay(del,0);
}
else t[next].ch[0]=0;
}
int main()
{
in(n);
insert(inf); insert(-inf);
for(lol i=1;i<=n;i++) {
lol a; in(a);
if(i==1) {
insert(a);
ans+=a;
}
else {
lol x=t[Next(a,0)].val;
lol y=t[Next(a,1)].val;
ans+=Min(abs(a-x),abs(a-y));
}
insert(a);
}
cout<<ans<<endl;
return 0;
}

博主蒟蒻,随意转载.但必须附上原文链接

http://www.cnblogs.com/real-l/