BZOJ1800 营业额统计

1588: [HNOI2002]营业额统计

Time Limit: 5 Sec   Memory Limit: 162 MB
Submit: 18663   Solved: 7817
[ Submit][ Status][ Discuss]

Description

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

Input

第一行为正整数 ,表示该公司从成立一直到现在的天数,接下来的n行每行有一个整数(有可能有负数) ,表示第i
天公司的营业额。
天数n<=32767,
每天的营业额ai <= 1,000,000。
最后结果T<=2^31

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


该题数据bug已修复.----2016.5.15


解析:

    直接用Treap求前驱和后继,然后分别计算与该数值的差,累加差的最小值即可。


代码:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <cmath>
#include <cctype>
#include <queue>
using namespace std;

const int Max=51000;
const int INF=1e9+7;
int n,root=1,tot,ans;
struct Treap{int l,r,val,data;};
Treap a[Max];

inline int get_int()
{
   int x=0,f=1;
   char c;
   for(c=getchar();(!isdigit(c))&&(c!='-');c=getchar());
   if(c=='-') {f=-1;c=getchar();}
   for(;isdigit(c);c=getchar()) x=(x<<3)+(x<<1)+c-'0';
   return x*f;
}

inline int NEW(int val)
{
   a[++tot].val=val;
   a[tot].data=rand();
   return tot;
}

inline void build()
{
   NEW(-INF);
   NEW(INF);
   a[1].r=2;
}

inline void zig(int &p)        //左旋 
{
   int q=a[p].l;
   a[p].l=a[q].r;a[q].r=p;p=q;
}

inline void zag(int &p)        //右旋 
{
   int q=a[p].r;
   a[p].r=a[q].l;a[q].l=p;p=q;
}

inline void Insert(int &p,int val)     //插入 
{
   if(p==0)
   {
   	 p=NEW(val);
   	 return;
   }
   if(val==a[p].val) return;
   if(val<a[p].val)
   {
   	 Insert(a[p].l,val);
   	 if(a[a[p].l].data>a[p].data) zig(p);
   }
   else
   {
   	 Insert(a[p].r,val);
   	 if(a[a[p].r].data>a[p].data) zag(p);
   }
}

inline int GetPre(int val)     //前驱 
{
   int ans=1,p=root;
   while(p)
   {
   	 if(a[p].val==val) return val;
   	 if(a[p].val<val&&a[p].val>a[ans].val) ans=p;
   	 a[p].val>val ? p=a[p].l : p=a[p].r;
   }
   return a[ans].val;
}

inline int GetNext(int val)     //后继 
{
   int ans=2,p=root;
   while(p)
   {
   	 if(a[p].val==val) return val;
   	 if(a[p].val>val&&a[p].val<a[ans].val) ans=p;
   	 a[p].val>val ? p=a[p].l : p=a[p].r;
   }
   return a[ans].val;
}

int main()
{
   //freopen("lx.in","r",stdin);
   //freopen("lx.out","w",stdout);

   n=get_int();
   build();
   for(int i=1;i<=n;i++)
   {
   	 int x=get_int();
   	 if(i==1) ans+=x;
   	 else
	 {
	   int Pre=GetPre(x),Next=GetNext(x);
	   if(Pre==-INF&&Next!=INF) ans+=Next-x;
	   if(Pre!=-INF&&Next==INF) ans+=x-Pre;
	   if(Pre!=-INF&&Next!=INF) ans+=min(x-Pre,Next-x);
     }
   	 Insert(root,x);
   }

   cout<<ans<<"\n";
   return 0;
}

猜你喜欢

转载自blog.csdn.net/m0_38083668/article/details/80023965