1588: [HNOI2002]营业额统计
Time Limit: 5 Sec Memory Limit: 162 MB
Submit: 18560 Solved: 7758
[Submit][Status][Discuss]
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
Sample Output
12
HINT
结果说明:5+|1-5|+|2-1|+|5-5|+|4-5|+|6-5|=5+4+1+0+1+1=12
该题数据bug已修复.—-2016.5.15
Source
第一次用伸展树,以前写过二叉查找树的插入删除,反正也是各种麻烦,这个只是多了个伸展操作,看懂了就好了。
#include<iostream>
#include<cstdio>
#include<string>
#include <cstring>
#include <stack>
#include <algorithm>
using namespace std;
#define INF 0x3f3f3f3f
struct node {
int value;
node* son[2];
node* father;
node(int v,node* f) {
son[0] = son[1] = NULL;
value = v;
father = f;
}
};
node *root = NULL;
inline int isson(node *f,node *s) {
return f->son[1] == s;
}
void rotate(node *p) {
node *f = p->father;
node *g = f->father;
int v = isson(f,p);
if (p->son[v ^ 1] != NULL) p->son[v ^ 1]->father = f;
f->son[v] = p->son[v^1];
p->son[v ^ 1] = f;
f->father = p;
p->father = g;
if (g != NULL) g->son[isson(g, f)] = p;
else root = p;
}
void splay(node* p,node* r) {
while (p->father != r) {
node *f = p->father;
node *g = f->father;
if (g == r) rotate(p);//单旋,当当前要伸展的结点的祖父为待转动到达的结点r,实际上是使其成为r的儿子
else {//其祖父结点仍然不是r时,两次旋转使其到达祖父的位置
if (isson(g, f) ^ isson(f, p)) rotate(p),rotate(p);//左左,右右
else rotate(f), rotate(p);//左右,右左
}
}
}
void insert(int value) {
if (root == NULL) {
root = new node(value, NULL);
return;
}
for (node *p = root; p != NULL; p = p->son[value >= p->value]) {
if (p->value == value) {
splay(p, NULL);
return;
}
else if (p->son[value >= p->value] == NULL) {
p->son[value >= p->value] = new node(value, p);
splay(p->son[value >= p->value], NULL);
return;
}
}
}
int search(int value) {
int Min = INF;
for (node *p = root; p != NULL; p = p->son[value >= p->value]) {
if (p->value == value) {
return 0;
}
else {
Min = min(Min, abs(p->value - value));
}
}
return Min;
}
void freenode() {
if (root == NULL) {
return;
}
stack<node*> s;
s.push(root);
while (!s.empty()) {
node *t = s.top();
s.pop();
if (t->son[0] != NULL) {
s.push(t->son[0]);
}
if (t->son[1] != NULL) {
s.push(t->son[1]);
}
free(t);
}
}
void init() {
freenode();
root = NULL;
}
int main() {
int n, x;
while (~scanf("%d", &n)) {
init();
scanf("%d", &x);
insert(x);
long long sum = x;
for (int i = 1; i < n; ++i) {
scanf("%d", &x);
sum = sum + search(x);
insert(x);
}
printf("%lld\n", sum);
}
return 0;
}