1296 营业额统计
2002年
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 大师 Master
题目描述 Description
Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。
Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析营业情况是一项相当复杂的工作。由于节假日,大减价或者是其他情况的时候,营业额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题。经济管理学上定义了一种最小波动值来衡量这种情况:
该天的最小波动值 = min{|该天以前某一天的营业额-该天营业额|}
当最小波动值越大时,就说明营业情况越不稳定。
而分析整个公司的从成立到现在营业情况是否稳定,只需要把每一天的最小波动值加起来就可以了。你的任务就是编写一个程序帮助Tiger来计算这一个值。
第一天的最小波动值为第一天的营业额。
输入描述 Input Description
第一行为正整数n(n<=32767),表示该公司从成立一直到现在的天数,接下来的n行每行有一个正整数ai(ai<=1000000),表示第i天公司的营业额。
输出描述 Output Description
输出文件仅有一个正整数,即每天最小波动值之和,小于231
样例输入 Sample Input
6
5
1
2
5
4
6
样例输出 Sample Output
12
数据范围及提示 Data Size & Hint
结果说明:5+|1-5|+|2-1|+|5-5|+|4-5|+|6-5|=5+4+1+0+1+1=12
题目链接:http://codevs.cn/problem/1296/
1 #include<cstdio> 2 #include<cstring> 3 #include<math.h> 4 #include<algorithm> 5 using namespace std; 6 const int maxn = 32800; 7 int MAX,MIN,INF=0x7fffffff; 8 void read(int &x) //读入优化 9 { 10 x=0; 11 int f=1; 12 char ch=getchar(); 13 while(ch<'0'||ch>'9') 14 { 15 if(ch=='-')f=-1; 16 ch=getchar(); 17 } 18 while(ch>='0'&&ch<='9') 19 { 20 x=x*10+ch-'0'; 21 ch=getchar(); 22 } 23 x*=f; 24 } 25 struct Splay 26 { 27 struct node 28 { 29 int l,r,date,f; 30 } T[maxn]; 31 int cnt,root; 32 Splay() //初始化 33 { 34 root=1; 35 memset(T,0,sizeof(T)); 36 cnt=1; 37 T[cnt].date=INF; 38 cnt++; 39 root=1; 40 insert_tree(root,-INF); 41 } 42 void insert_tree(int now,int num) //插入 43 { 44 if(num<T[now].date) 45 { 46 if(T[now].l)insert_tree(T[now].l,num); 47 else 48 { 49 T[now].l=cnt; 50 T[cnt].f=now; 51 T[cnt++].date=num; 52 } 53 } 54 else 55 { 56 if(T[now].r)insert_tree(T[now].r,num); 57 else 58 { 59 T[now].r=cnt; 60 T[cnt].f=now; 61 T[cnt++].date=num; 62 } 63 } 64 65 } 66 void right_rotation(int x,int f,int ff) //右旋 67 { 68 T[T[x].r].f=f; 69 T[f].l=T[x].r; 70 T[f].f=x; 71 T[x].r=f; 72 if(ff==0) 73 T[x].f=0; 74 else 75 { 76 T[x].f=ff; 77 if(T[ff].l==f) 78 T[ff].l=x; 79 else 80 T[ff].r=x; 81 } 82 } 83 void left_rotation(int x,int f,int ff) //左旋 84 { 85 T[T[x].l].f=f; 86 T[f].r=T[x].l; 87 T[f].f=x; 88 T[x].l=f; 89 if(ff==0) 90 T[x].f=0; 91 else 92 { 93 T[x].f=ff; 94 if(T[ff].l==f) 95 T[ff].l=x; 96 else 97 T[ff].r=x; 98 } 99 } 100 int splay(int now) //splay 5种操作 101 { 102 root=now; 103 while(1) 104 { 105 if(T[now].f==0) 106 break; 107 else if(T[T[now].f].f==0) 108 { 109 if(T[T[now].f].l==now)right_rotation(now,T[now].f,0); 110 else left_rotation(now,T[now].f,0); 111 break; 112 } 113 else 114 { 115 int f=T[now].f,ff=T[T[now].f].f; 116 if(T[f].l==now&&T[ff].l==f) 117 { 118 right_rotation(f,ff,T[ff].f); 119 right_rotation(now,T[now].f,T[T[now].f].f); 120 } 121 else if(T[f].r==now&&T[ff].r==f) 122 { 123 left_rotation(f,ff,T[ff].f); 124 left_rotation(now,T[now].f,T[T[now].f].f); 125 } 126 else if(T[f].l==now) 127 { 128 right_rotation(now,T[now].f,T[T[now].f].f); 129 left_rotation(now,T[now].f,T[T[now].f].f); 130 } 131 else 132 { 133 left_rotation(now,T[now].f,T[T[now].f].f); 134 right_rotation(now,T[now].f,T[T[now].f].f); 135 } 136 } 137 } 138 } 139 void find_low_tree(int now,int x) //二分查找寻找第一个<=x的数 140 { 141 if(T[now].date<=x) 142 { 143 if(T[now].date>MIN)MIN=T[now].date; 144 if(T[now].r) 145 find_low_tree(T[now].r,x); 146 } 147 else 148 { 149 if(T[now].l) 150 find_low_tree(T[now].l,x); 151 } 152 } 153 void find_high_tree(int now,int x) //二分查找寻找第一个>=x的数 154 { 155 if(T[now].date>=x) 156 { 157 if(T[now].date<MAX)MAX=T[now].date; 158 if(T[now].l) 159 find_high_tree(T[now].l,x); 160 } 161 else 162 { 163 if(T[now].r) 164 find_high_tree(T[now].r,x); 165 } 166 } 167 }tree; 168 int main() 169 { 170 int n,num,sum=0; 171 scanf("%d",&n); 172 for(int i=1; i<=n; i++) 173 { 174 read(num); 175 if(i==1) 176 { 177 sum+=num; 178 tree.insert_tree(tree.root,num); 179 } 180 else 181 { 182 MIN=-INF,MAX=INF; 183 tree.find_low_tree(tree.root,num); 184 if(MIN==num) 185 continue; 186 tree.find_high_tree(tree.root,num); 187 if(MAX==INF) 188 sum+=abs(MIN-num); 189 else if(MIN==-INF) 190 sum+=abs(MAX-num); 191 else 192 { 193 if(abs(MAX-num)<abs(MIN-num)) 194 sum+=abs(MAX-num); 195 else 196 sum+=abs(MIN-num); 197 } 198 tree.insert_tree(tree.root,num); 199 tree.splay(tree.cnt-1); 200 } 201 } 202 printf("%d ",sum); 203 return 0; 204 }