bzoj1588 [HNOI2002]营业额统计(Treap)
2015-12-03 16:18
337 查看
1588: [HNOI2002]营业额统计
Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 11485 Solved: 4062
[Submit][Status][Discuss]
Description
营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。
Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析营业情况是一项相当复杂的工作。由于节假日,大减价或者是其他情况的时候,营业
额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题。经济管理学上定义了
一种最小波动值来衡量这种情况: 该天的最小波动值 当最小波动值越大时,就说明营业情况越不稳定。
而分析整个公司的从成立到现在营业情况是否稳定,只需要把每一天的最小波动值加起来就可以了。你的任务就是编写一个程序帮助Tiger来计算这一个值。
第一天的最小波动值为第一天的营业额。 输入输出要求
Input
第一行为正整数 ,表示该公司从成立一直到现在的天数,接下来的n行每行有一个整数(有可能有负数) ,表示第i天公司的营业额。Output
输出文件仅有一个正整数,即Sigma(每天最小的波动值) 。结果小于2^31 。Sample Input
65
1
2
5
4
6
Sample Output
12HINT
结果说明: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
Source
【思路】Treap。
构造一个集合S,对于每一个x提供查找S中比x小的最大的数和比x大的最小的数。
可用Treap完成(此题原数据可过,bzoj上的数据不再深究)。
【代码】
#include<cstdio> #include<ctime> #include<cstring> #include<cstdlib> #include<iostream> #define FOR(a,b,c) for(int a=(b);a<=(c);a++) using namespace std; struct Node{ Node* ch[2]; int v,r; Node(int w) :v(w) { ch[0]=ch[1]=NULL; r=rand(); } int cmp(int x) const { if(x==v) return -1; return x<v? 0:1; } }; Node* root; void rotate(Node* &o,int d) { Node*k=o->ch[d^1]; o->ch[d^1]=k->ch[d]; k->ch[d]=o; o=k; } void insert(Node* &o,int x) { if(o==NULL) o=new Node(x); else { int d=o->cmp(x); if(d==-1) return ; insert(o->ch[d],x); if(o->ch[d]->r > o->r) rotate(o,d^1); } } void removetree(Node* &o) { if(o->ch[0]!=NULL) removetree(o->ch[0]); if(o->ch[1]!=NULL) removetree(o->ch[1]); delete o , o=NULL; } void query1(Node* o,int x,int& ans) { if(o==NULL) return ; if(o->v <= x) { ans=o->v; query1(o->ch[1],x,ans); } else query1(o->ch[0],x,ans); } void query2(Node* o,int x,int& ans) { if(o==NULL) return ; if(o->v >= x) { ans=o->v; query2(o->ch[0],x,ans); } else query2(o->ch[1],x,ans); } int n; int abs(int x) { return x<0? -x:x; } int main() { //freopen("in.in","r",stdin); //freopen("out.out","w",stdout); while(scanf("%d",&n)==1) { int x,ans=0,tmp,ta; for(int i=0;i<n;i++) { if(scanf("%d",&x)==EOF) x=0; if(!i) { ans+=x; root=new Node(x); continue; } query1(root,x,tmp); ta=abs(x-tmp); query2(root,x,tmp); ta=min(ta,abs(x-tmp)); insert(root,x); ans+=ta; } printf("%d\n",ans); removetree(root); } return 0; }
相关文章推荐
- JavaEE_Mybatis_SpringMVC_Mybatis_lesson13_多对多关联映射(ResultMap)
- 【Codeforces Round 330 (Div 2)E】【贪心 暴力】Edo and Magnets 给定矩形最多去除m个,最小面积矩形使得覆盖所有小矩形重心
- ecshop仿京东商城二次开发
- (三十九)运算符
- html5系列:伪主动触发input:file的click事件
- 算法学习之Honer's Rule
- 优化查询
- Android四大基本组件_Activity
- 一些简单的shell脚本实例 转
- 剑指offer6 旋转数组的最小数字
- 复数类
- Unity-NGUI不规则点击碰撞处理
- html5系列:利用html5 file api读取本地文件(如图片、PDF等)
- cygwin和mingw的区别
- iOS LLDB调试器和断点调试
- Intent 跳转
- spring mybatis mvc cache 缓存 二级缓存
- Android Studio集成Genymotion插件
- lnmp全面优化集合nginx+mysql+php
- 6)图[6]各顶点之间的最短路径