bzoj1588:[HNOI2002]营业额统计
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
5
1
2
5
4
6
Sample Output
12
HINT
题解
先查前驱后继,再插入。
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #define inf 1<<29 5 #define maxn 50000 6 int cnt,flag,n,root,ret,ansx; 7 using namespace std; 8 struct treap{ 9 int lc,rc,key,pri,siz,val; 10 }a[maxn]; 11 void pushup(int o) 12 { 13 a[o].siz=a[a[o].lc].siz+a[a[o].rc].siz+a[o].val; 14 } 15 void lturn(int &o) 16 { 17 int t=a[o].rc; 18 a[o].rc=a[t].lc; 19 a[t].lc=o; 20 a[t].siz=a[o].siz; 21 pushup(o); 22 o=t; 23 return ; 24 } 25 void rturn(int &o) 26 { 27 int t=a[o].lc; 28 a[o].lc=a[t].rc; 29 a[t].rc=o; 30 a[t].siz=a[o].siz; 31 pushup(o); 32 o=t; 33 return ; 34 } 35 void insert(int &o,int x) 36 { 37 if(!o) 38 { 39 o=++cnt; 40 a[o]=(treap){0,0,x,rand(),1,1}; 41 return ; 42 } 43 a[o].siz++; 44 if(a[o].key==x)a[o].val++; 45 else if(a[o].key>x) 46 { 47 insert(a[o].lc,x); 48 if(a[a[o].lc].pri>a[o].pri)rturn(o); 49 } 50 else 51 { 52 insert(a[o].rc,x); 53 if(a[a[o].rc].pri>a[o].pri)lturn(o); 54 } 55 } 56 void que_pro(int o,int x) 57 { 58 if(!o)return ; 59 if(a[o].key==x) 60 { 61 ret=a[o].key; 62 return ; 63 } 64 if(a[o].key>x)que_pro(a[o].lc,x); 65 else 66 { 67 ret=a[o].key; 68 que_pro(a[o].rc,x); 69 } 70 return ; 71 } 72 void que_sub(int o,int x) 73 { 74 if(!o)return ; 75 if(a[o].key==x) 76 { 77 ret=a[o].key; 78 return ; 79 } 80 if(a[o].key<x)que_sub(a[o].rc,x); 81 else 82 { 83 ret=a[o].key; 84 que_sub(a[o].lc,x); 85 } 86 return ; 87 } 88 void work(int x) 89 { 90 int ans=inf; 91 ret=-inf; 92 que_pro(root,x); 93 ans=min(ans,abs(x-ret)); 94 ret=inf; 95 que_sub(root,x); 96 ans=min(ans,abs(x-ret)); 97 ansx+=ans; 98 return ; 99 } 100 int main() 101 { 102 int k; 103 scanf("%d",&n); 104 scanf("%d",&k); 105 srand(n); 106 ansx=k; 107 insert(root,k); 108 for(int i=1 ; i<n ; ++i) 109 { 110 scanf("%d",&k); 111 work(k);insert(root,k); 112 } 113 printf("%d",ansx); 114 return 0; 115 }
结果说明:5+|1-5|+|2-1|+|5-5|+|4-5|+|6-5|=5+4+1+0+1+1=12