营业额统计 2011-12-20
营业额统计
(turnover.exe)
Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。
Tiger 拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析营业情况是一项相当复杂的工作。由于节假日,大减价或者是其他情况的时候,营业额会出现一 定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题。经济管理学上定义了一种最小波 动值来衡量这种情况:
该天的最小波动值
当最小波动值越大时,就说明营业情况越不稳定。
而分析整个公司的从成立到现在营业情况是否稳定,只需要把每一天的最小波动值加起来就可以了。你的任务就是编写一个程序帮助Tiger来计算这一个值。
第一天的最小波动值为第一天的营业额。
l 输入输出要求
输入由文件’turnover.in’读入。
第一行为正整数,表示该公司从成立一直到现在的天数,接下来的n行每行有一个正整数,表示第i天公司的营业额。
输出到文件’turnover.out’。
输出文件仅有一个正整数,即。结果小于。
l 输入输出样例
Turnover.in
Turnover.out
6
5
1
2
5
4
6
12
结果说明:5+|1-5|+|2-1|+|5-5|+|4-5|+|6-5|=5+4+1+0+1+1=12
————————————————————————
平衡树优化。
————————————————————————
1 Program Stone; 2 3 var i,j,k,n,root,qu,ji:longint; 4 5 a:array[0..50000]of longint; 6 7 t,lc,rc,f:array[0..50000]of longint; 8 9 ans:int64; 10 11 12 13 procedure rightturn(x:longint); //右旋 14 15 var i,j:longint; 16 17 begin 18 19 i:=f[x]; 20 21 if lc[f[i]]=i then lc[f[i]]:=x else rc[f[i]]:=x; 22 23 f[x]:=f[i]; 24 25 26 27 lc[i]:=rc[x]; 28 29 f[lc[i]]:=i; 30 31 32 33 rc[x]:=i; 34 35 f[i]:=x; 36 37 end; 38 39 procedure leftturn(x:longint); //左旋 40 41 var i:longint; 42 43 begin 44 45 i:=f[x]; 46 47 if lc[f[i]]=i then lc[f[i]]:=x else rc[f[i]]:=x; 48 49 f[x]:=f[i]; 50 51 52 53 rc[i]:=lc[x]; 54 55 f[rc[i]]:=i; 56 57 58 59 lc[x]:=i; 60 61 f[i]:=x; 62 63 end; 64 65 66 67 procedure findleft(x:longint); //寻找前驱,即寻找根节点的左子树中最大的节点 68 69 begin 70 71 if rc[x]=0 then qu:=x else findleft(rc[x]); 72 73 end; 74 75 procedure findright(x:longint); //寻找后继,即寻找根节点的右子树中的最小节点 76 77 begin 78 79 if lc[x]=0 then ji:=x else findright(lc[x]); 80 81 end; 82 83 84 85 procedure add(x,o:longint); //在二叉树中添加一个节点 86 87 var i,j,k:longint; 88 89 begin 90 91 if a[o]>=a[x] then begin 92 93 if rc[x]=0 then begin rc[x]:=o;f[o]:=x;end //判断是否可以插入节点。 94 95 else add(rc[x],o); 96 97 end 98 99 else begin 100 101 if lc[x]=0 then begin lc[x]:=o;f[o]:=x;end 102 103 else add(lc[x],o); 104 105 end; 106 107 end; 108 109 110 111 procedure promote(x:longint); //splay旋转。共六种旋转方式 112 113 var i,j,k:longint; 114 115 begin 116 117 k:=f[x]; 118 119 if x=lc[k] then begin 120 121 if f[k]=0 then rightturn(x) 122 123 else if lc[f[k]]=k then begin 124 125 rightturn(k); 126 127 rightturn(x); 128 129 end 130 131 else begin 132 133 rightturn(x); 134 135 leftturn(x); 136 137 end; 138 139 end 140 141 else begin 142 143 if f[k]=0 then leftturn(x) 144 145 else if rc[f[k]]=k then begin 146 147 leftturn(k); 148 149 leftturn(x); 150 151 end 152 153 else begin 154 155 leftturn(x); 156 157 rightturn(x); 158 159 end; 160 161 end; 162 163 end; 164 165 function min(a,b:longint):longint; 166 167 begin 168 169 if a<b then min:=a else min:=b; 170 171 end; 172 173 Begin 174 175 assign(input,'turnover.in');assign(output,'turnover.out'); 176 177 reset(input);rewrite(output); 178 179 readln(n); 180 181 readln(a[1]); 182 183 ans:=a[1];root:=1; 184 185 for i:=2 to n do 186 187 begin 188 189 readln(a[i]); 190 191 add(root,i); 192 193 while f[i]<>0 do promote(i); //将i节点旋转到根 194 195 root:=i; 196 197 findleft(lc[i]); 198 199 findright(rc[i]); 200 201 inc(ans,min(abs(a[qu]-a[i]),abs(a[ji]-a[i]))); 202 203 end; 204 205 writeln(ans); 206 207 close(input);close(output); 208 209 end.
_____MildTheorem