[BZOJ1588][HNOI2002]营业额统计

Posted xjr_01

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[BZOJ1588][HNOI2002]营业额统计相关的知识,希望对你有一定的参考价值。

[BZOJ1588][HNOI2002]营业额统计

试题描述

营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况。 Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额。分析营业情况是一项相当复杂的工作。由于节假日,大减价或者是其他情况的时候,营业额会出现一定的波动,当然一定的波动是能够接受的,但是在某些时候营业额突变得很高或是很低,这就证明公司此时的经营状况出现了问题。经济管理学上定义了一种最小波动值来衡量这种情况: 该天的最小波动值 当最小波动值越大时,就说明营业情况越不稳定。 而分析整个公司的从成立到现在营业情况是否稳定,只需要把每一天的最小波动值加起来就可以了。你的任务就是编写一个程序帮助Tiger来计算这一个值。 第一天的最小波动值为第一天的营业额。 ? 输入输出要求

输入

第一行为正整数 ,表示该公司从成立一直到现在的天数,接下来的n行每行有一个整数(有可能有负数) ,表示第i天公司的营业额。

输出

输出文件仅有一个正整数,即Sigma(每天最小的波动值) 。结果小于2^31 。

输入示例

6
5
1
2
5
4
6

输出示例

12

数据规模及约定

n ≤ 50000

题解

简单的平衡树操作。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <cmath>
using namespace std;

int read() {
	int x = 0, f = 1; char c = getchar();
	while(!isdigit(c)){ if(c == ‘-‘) f = -1; c = getchar(); }
	while(isdigit(c)){ x = x * 10 + c - ‘0‘; c = getchar(); }
	return x * f;
}

#define maxn 50010
#define oo 2147483647
struct Node {
	int v, r, minv, maxv;
	Node() {}
	Node(int _, int __): v(_), r(__) {}
} ns[maxn];
int ToT, rt, ch[2][maxn], fa[maxn];

void maintain(int o) {
	ns[o].minv = ns[o].maxv = ns[o].v;
	for(int i = 0; i < 2; i++) if(ch[i][o])
		ns[o].minv = min(ns[o].minv, ns[ch[i][o]].minv), ns[o].maxv = max(ns[o].maxv, ns[ch[i][o]].maxv);
	return ;
}
void rotate(int u) {
	int y = fa[u], z = fa[y], l = 0, r = 1;
	if(z) ch[ch[1][z]==y][z] = u;
	if(ch[1][y] == u) swap(l, r);
	fa[u] = z; fa[y] = u; fa[ch[r][u]] = y;
	ch[l][y] = ch[r][u]; ch[r][u] = y;
	maintain(y); maintain(u);
	return ;
}
void insert(int& o, int v) {
	if(!o) {
		ns[o = ++ToT] = Node(v, rand());
		return maintain(o);
	}
	bool d = v > ns[o].v;
	insert(ch[d][o], v); fa[ch[d][o]] = o;
	if(ns[ch[d][o]].r > ns[o].r) {
		int t = ch[d][o];
		rotate(t); o = t;
	}
	return maintain(o);
}
int fans;
void Find(int o, int v) {
	if(!o) return ;
	if(ns[o].v == v){ fans = 0; return ; }
	fans = min(fans, abs(v - ns[o].v));
	for(int i = 0; i < 2; i++) if(ch[i][o])
		fans = min(fans, min(abs(v - ns[ch[i][o]].minv), abs(v - ns[ch[i][o]].maxv)));
	bool d = v > ns[o].v;
	Find(ch[d][o], v);
	return ;
}

int main() {
	int q = read(), ans = read();
	insert(rt, ans); q--;
	while(q--) {
		int v = read();
		fans = oo; Find(rt, v);
		ans += fans;
//		printf("get: %d\n", fans);
		insert(rt, v);
	}
	printf("%d\n", ans);
	
	return 0;
}

 

以上是关于[BZOJ1588][HNOI2002]营业额统计的主要内容,如果未能解决你的问题,请参考以下文章

bzoj1588: [HNOI2002]营业额统计

bzoj1588:[HNOI2002]营业额统计

[BZOJ1588][HNOI2002]营业额统计

bzoj 1588: [HNOI2002]营业额统计 treap

BZOJ1588: [HNOI2002]营业额统计[BST]

bzoj1588[HNOI2002]营业额统计 treap