题目描述
Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。
Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析营业情况是一项相当复杂的工作。由于节假日,大减价或者是其他情况的时候,营业额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题。经济管理学上定义了一种最小波动值来衡量这种情况:
当最小波动值越大时,就说明营业情况越不稳定。
而分析整个公司的从成立到现在营业情况是否稳定,只需要把每一天的最小波动值加起来就可以了。你的任务就是编写一个程序帮助Tiger来计算这一个值。
第一天的最小波动值为第一天的营业额。
该天的最小波动值=min{|该天以前某一天的营业额-该天营业额|}。
这道题是比较简单的, 这次使用了fhq-treap, fhq-treap的优点是好写.
相对treap, 我觉得找前驱后继太繁琐了
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
using namespace std;
struct Node{
Node * left, * right;
int value, priority;
Node(){};
Node(Node * l, Node * r, int v, int p): left(l), right(r), value(v), priority(p){};
};
typedef pair<Node *, Node *> pNN;
Node * null = new Node(), * root = null;
void print(Node * o){
if(o == null){
printf(" NULL ");
return;
}
print(o->left);
printf(" %d ", o->value);
print(o->right);
}
pNN split_l(Node * o, int val){
if(o == null){
return make_pair(null, null);
}
pNN result;
if(o->value <= val){
result = split_l(o->right, val);
o->right = result.first;
result.first = o;
}
else{
result = split_l(o->left, val);
o->left = result.second;
result.second = o;
}
return result;
}
pNN split_r(Node * o, int val){
if(o == null){
return make_pair(null, null);
}
pNN result;
if(o->value < val){
result = split_r(o->right, val);
o->right = result.first;
result.first = o;
}
else{
result = split_r(o->left, val);
o->left = result.second;
result.second = o;
}
return result;
}
Node * merge(Node * left, Node * right){
if(left == null){
return right;
}
if(right == null){
return left;
}
if(left->priority < right->priority){
left->right = merge(left->right, right);
return left;
}
else{
right->left = merge(left, right->left);
return right;
}
}
int getMin(Node * o){
while(o->left != null){
o = o->left;
}
return o->value;
}
int getMax(Node * o){
while(o->right != null){
o = o->right;
}
return o->value;
}
void insert(int val){
pNN first = split_l(root, val);
pNN second = split_r(first.first, val);
Node * node = new Node(null, null, val, rand());
second.second = merge(second.second, node);
root = merge(merge(second.first, second.second), first.second);
}
int getPre(int val){
pNN first = split_l(root, val);
pNN second = split_r(first.first, val);
if(second.second != null){
root = merge(merge(second.first, second.second), first.second);
return second.second->value;
}
root = merge(merge(second.first, second.second), first.second);
pNN tree = split_r(root, val);
int rst = getMax(tree.first);
root = merge(tree.first, tree.second);
return rst;
}
int getNext(int val){
pNN tree = split_l(root, val);
int rst = getMin(tree.second);
root = merge(tree.first, tree.second);
return rst;
}
int main(){
null->left = null->right = null;
// insert(-0x3f3f3f3f), insert(0x3f3f3f3f);
int n, tmp;
scanf("%d", &n);
scanf("%d", &tmp);
insert(tmp);
long long sum = tmp;
print(root);
printf("sum %lld\n", sum);
for(int i = 1; i < n; ++i){
scanf("%d", &tmp);
sum += min(getNext(tmp) - tmp, tmp - getPre(tmp));
insert(tmp);
}
printf("%lld\n", sum);
return 0;
}