BZOJ 1588 营业额统计
Description
营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。 Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析营业情况是一项相当复杂的工作。由于节假日,大减价或者是其他情况的时候,营业额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题。经济管理学上定义了一种最小波动值来衡量这种情况: 该天的最小波动值 当最小波动值越大时,就说明营业情况越不稳定。 而分析整个公司的从成立到现在营业情况是否稳定,只需要把每一天的最小波动值加起来就可以了。你的任务就是编写一个程序帮助Tiger来计算这一个值。 第一天的最小波动值为第一天的营业额。 输入输出要求
Input
第一行为正整数 ,表示该公司从成立一直到现在的天数,接下来的n行每行有一个整数(有可能有负数) ,表示第i天公司的营业额。
Output
输出文件仅有一个正整数,即Sigma(每天最小的波动值) 。结果小于2^31 。
Sample Input
6
5
1
2
5
4
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
平衡树裸题。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cmath> 4 using namespace std; 5 #define maxn 33000 6 int n,share[maxn]; 7 int lc[maxn],rc[maxn],father[maxn],root,ans; 8 9 inline int small(int a,int b) {if (a < b) return a; return b;} 10 11 inline void work(); 12 inline void zig(int); 13 inline void zag(int); 14 inline int find(int); 15 inline void ins(int); 16 inline void splay(int); 17 18 int main() 19 { 20 freopen("1588.in","r",stdin); 21 freopen("1588.out","w",stdout); 22 scanf("%d",&n); 23 int i; 24 for (i = 1;i<=n;i++) 25 scanf("%d",share+i); 26 work(); 27 printf("%d",ans); 28 fclose(stdin); fclose(stdout); 29 return 0; 30 } 31 32 inline int find(int a) 33 { 34 int ret = 1000000,now = root; 35 ret = small(abs(share[now]-a),ret); 36 now = rc[root]; 37 while (now > 0) 38 { 39 if (share[now] == a) 40 return 0; 41 ret = small(abs(share[now]-a),ret); 42 if (share[now] > a) 43 now = rc[now]; 44 else now = lc[now]; 45 } 46 now = lc[root]; 47 while (now > 0) 48 { 49 if (share[now] == a) 50 return 0; 51 ret = small(abs(share[now]-a),ret); 52 if (share[now] > a) 53 now = rc[now]; 54 else now = lc[now]; 55 } 56 return ret; 57 } 58 59 inline void work() 60 { 61 ans = share[1]; root = 1; 62 int i,j,k; 63 for (i = 2;i<=n;i++) 64 { 65 k = find(share[i]); 66 ans += k; 67 if (k != 0) 68 ins(i); 69 } 70 } 71 72 inline void ins(int a) 73 { 74 int last,now; 75 now = root; 76 while (now != 0) 77 { 78 last = now; 79 if (share[now] > share[a]) 80 now = rc[now]; 81 else now = lc[now]; 82 } 83 father[a] = last; 84 if (share[a] > share[last]) 85 lc[last] = a; 86 else rc[last] = a; 87 splay(a); 88 root = a; 89 } 90 91 inline void zig(int x) 92 { 93 int y = father[x]; 94 father[x] = father[y]; 95 if (father[y] != 0) 96 { 97 if (lc[father[y]] == y) 98 lc[father[y]] = x; 99 else rc[father[y]] = x; 100 } 101 father[y] = x; 102 lc[y] = rc[x]; 103 if (rc[x] != 0) 104 father[rc[x]] = y; 105 rc[x] = y; 106 } 107 108 inline void zag(int x) 109 { 110 int y = father[x]; 111 father[x] = father[y]; 112 if (father[y] != 0) 113 { 114 if (lc[father[y]] == y) 115 lc[father[y]] = x; 116 else rc[father[y]] = x; 117 } 118 father[y] = x; 119 rc[y] = lc[x]; 120 if (lc[x] != 0) 121 father[lc[x]] = y; 122 lc[x] = y; 123 } 124 125 inline void splay(int a) 126 { 127 while (father[a] != 0) 128 { 129 if (father[father[a]] == 0) 130 { 131 if (a == lc[father[a]]) 132 zig(a); 133 else zag(a); 134 } 135 else 136 { 137 if (lc[father[father[a]]]==father[a] && lc[father[a]] == a) 138 { 139 zig(father[a]), 140 zig(a); 141 } 142 else if (lc[father[father[a]]]==father[a] && rc[father[a]] == a) 143 { 144 zag(a); 145 zig(a); 146 } 147 else if (rc[father[father[a]]]==father[a] && lc[father[a]] == a) 148 { 149 zig(a); 150 zag(a); 151 } 152 else if (rc[father[father[a]]]==father[a] && rc[father[a]] == a) 153 { 154 zag(father[a]); 155 zag(a); 156 } 157 } 158 } 159 }
高考结束,重新回归。