题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1588

题意:详见题面,中文

思路:平衡树的模板题。 可用Treap,Splay,Scapegoat Tree

【替罪羊树代码】

#define _CRT_SECURE_NO_DEPRECATE
#include<stdio.h>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<queue>
#include<math.h>
#include<time.h>
#include<vector>
#include<iostream>
using namespace std;
typedef long long int LL;
const int INF = 0x3f3f3f3f;
typedef long long LL;
namespace Scapegoat_Tree {
#define MAXN (1000000 + 10)
const double alpha = 0.75;
struct Node {
Node * ch[];
int key, size, cover; // size为有效节点的数量,cover为节点总数量
bool exist; // 是否存在(即是否被删除)
void PushUp(void) {
size = ch[]->size + ch[]->size + (int)exist;
cover = ch[]->cover + ch[]->cover + ;
}
bool isBad(void) { // 判断是否需要重构
return ((ch[]->cover > cover * alpha + ) ||
(ch[]->cover > cover * alpha + ));
}
};
struct STree {
protected:
Node mem_poor[MAXN]; //内存池,直接分配好避免动态分配内存占用时间
Node *tail, *root, *null; // 用null表示NULL的指针更方便,tail为内存分配指针,root为根
Node *bc[MAXN]; int bc_top; // 储存被删除的节点的内存地址,分配时可以再利用这些地址 Node * NewNode(int key) {
Node * p = bc_top ? bc[--bc_top] : tail++;
p->ch[] = p->ch[] = null;
p->size = p->cover = ; p->exist = true;
p->key = key;
return p;
}
void Travel(Node * p, vector<Node *>&v) {
if (p == null) return;
Travel(p->ch[], v);
if (p->exist) v.push_back(p); // 构建序列
else bc[bc_top++] = p; // 回收
Travel(p->ch[], v);
}
Node * Divide(vector<Node *>&v, int l, int r) {
if (l >= r) return null;
int mid = (l + r) >> ;
Node * p = v[mid];
p->ch[] = Divide(v, l, mid);
p->ch[] = Divide(v, mid + , r);
p->PushUp(); // 自底向上维护,先维护子树
return p;
}
void Rebuild(Node * &p) {
static vector<Node *>v; v.clear();
Travel(p, v); p = Divide(v, , v.size());
}
Node ** Insert(Node *&p, int val) {
if (p == null) {
p = NewNode(val);
return &null;
}
else {
p->size++; p->cover++; // 返回值储存需要重构的位置,若子树也需要重构,本节点开始也需要重构,以本节点为根重构
Node ** res = Insert(p->ch[val >= p->key], val);
if (p->isBad()) res = &p;
return res;
}
}
void Erase(Node *p, int id) {
p->size--;
int offset = p->ch[]->size + p->exist;
if (p->exist && id == offset) {
p->exist = false;
return;
}
else {
if (id <= offset) Erase(p->ch[], id);
else Erase(p->ch[], id - offset);
}
}
public:
void Init(void) {
tail = mem_poor;
null = tail++;
null->ch[] = null->ch[] = null;
null->cover = null->size = null->key = ;
root = null; bc_top = ;
}
STree(void) { Init(); } void Insert(int val) {
Node ** p = Insert(root, val);
if (*p != null) Rebuild(*p);
}
int Rank(int val) { //相同值取最小的排名
Node * now = root;
int ans = ;
while (now != null) { // 非递归求排名
if (now->key >= val) now = now->ch[];
else {
ans += now->ch[]->size + now->exist;
now = now->ch[];
}
}
return ans;
}
int Kth(int k) { //支持相同值
Node * now = root;
while (now != null) { // 非递归求第K大
if (now->ch[]->size + == k && now->exist) return now->key;
else if (now->ch[]->size >= k) now = now->ch[];
else k -= now->ch[]->size + now->exist, now = now->ch[];
}
}
void Erase(int k) {
Erase(root, Rank(k));
if (root->size < alpha * root->cover) Rebuild(root);
}
void Erase_kth(int k) {
Erase(root, k);
if (root->size < alpha * root->cover) Rebuild(root);
}
};
#undef MAXN
}
using namespace Scapegoat_Tree;
STree Scapegoat;
int main(){
#ifdef kirito
freopen("in.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
// int start = clock();
int n,val;
while (~scanf("%d", &n)){
LL sum=;
for (int i = ; i <= n; i++){
scanf("%d", &val);
if (i == ){
sum += val;
}
else{
int valRank = Scapegoat.Rank(val);
int a = abs(Scapegoat.Kth(valRank) - val);
int b = abs(Scapegoat.Kth(valRank - ) - val);
int c = abs(Scapegoat.Kth(val + ) - val);
sum += min(a, min(b, c));
}
Scapegoat.Insert(val);
}
printf("%d\n", sum);
/* DEBUG INFO
vector<Node *> xx;
_t.Travel(_t.root, xx);
cout << "::";
for(int i = 0; i < xx.size(); i++) cout << xx[i]->key << ' '; cout << endl;
*/
}
//#ifdef LOCAL_TIME
// cout << "[Finished in " << clock() - start << " ms]" << endl;
//#endif
return ;
}

【Splay代码】

#define _CRT_SECURE_NO_DEPRECATE
#include<stdio.h>
#include<string.h>
#include<cstring>
#include<algorithm>
#include<queue>
#include<math.h>
#include<time.h>
#include<vector>
#include<iostream>
using namespace std;
typedef long long int LL;
const int MAXN = 1e6 + ;
const int INF = 0x3f3f3f3f;
int cnt, rt;
struct Tree
{
int key, size, fa, son[];
void set(int _key, int _size, int _fa)
{
key = _key;
size = _size;
fa = _fa;
son[] = son[] = ;
}
}T[MAXN]; inline void PushUp(int x)
{
T[x].size = T[T[x].son[]].size + T[T[x].son[]].size + ;
} inline void Rotate(int x, int p)
{
int y = T[x].fa;
T[y].son[!p] = T[x].son[p];
T[T[x].son[p]].fa = y;
T[x].fa = T[y].fa;
if (T[x].fa)
T[T[x].fa].son[T[T[x].fa].son[] == y] = x;
T[x].son[p] = y;
T[y].fa = x;
PushUp(y);
PushUp(x);
} void Splay(int x, int To)
{
while (T[x].fa != To)
{
if (T[T[x].fa].fa == To)
Rotate(x, T[T[x].fa].son[] == x);
else
{
int y = T[x].fa, z = T[y].fa;
int p = (T[z].son[] == y);
if (T[y].son[p] == x)
Rotate(x, !p), Rotate(x, p);
else
Rotate(y, p), Rotate(x, p);
}
}
if (To == ) rt = x;
} int find(int key)
{
int x = rt;
while (x && T[x].key != key)
x = T[x].son[key > T[x].key];
if (x) Splay(x, );
return x;
} int prev()
{
int x = T[rt].son[];
if (!x) return ;
while (T[x].son[])
x = T[x].son[];
//Splay(x, 0);
return x;
} int succ()
{
int x = T[rt].son[];
if (!x) return ;
while (T[x].son[])
x = T[x].son[];
//Splay(x, 0);
return x;
} void Insert(int key)
{
if (!rt)
T[rt = cnt++].set(key, , );
else
{
int x = rt, y = ;
while (x)
{
y = x;
x = T[x].son[key > T[x].key];
}
T[x = cnt++].set(key, , y);
T[y].son[key > T[y].key] = x;
Splay(x, );
}
} void Delete(int key)
{
int x = find(key);
if (!x) return;
int y = T[x].son[];
while (T[y].son[])
y = T[y].son[];
int z = T[x].son[];
while (T[z].son[])
z = T[z].son[];
if (!y && !z)
{
rt = ;
return;
}
if (!y)
{
Splay(z, );
T[z].son[] = ;
PushUp(z);
return;
}
if (!z)
{
Splay(y, );
T[y].son[] = ;
PushUp(y);
return;
}
Splay(y, );
Splay(z, y);
T[z].son[] = ;
PushUp(z);
PushUp(y);
} int GetPth(int p)
{
if (!rt) return ;
int x = rt, ret = ;
while (x)
{
if (p == T[T[x].son[]].size + )
break;
if (p>T[T[x].son[]].size + )
{
p -= T[T[x].son[]].size + ;
x = T[x].son[];
}
else
x = T[x].son[];
}
Splay(x, );
return x;
} int GetRank(int key)
{
if (!rt) return ;
int x = rt, ret = , y;
while (x)
{
y = x;
if (T[x].key <= key)
{
ret += T[T[x].son[]].size + ;
x = T[x].son[];
}
else
x = T[x].son[];
}
Splay(y, );
return ret;
}
int main(){
//#ifdef kirito
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
//#endif
// int start = clock();
int n;
while (~scanf("%d", &n)){
LL ans = ; rt = ; cnt = ; T[].set(INF, , );
for (int i = ; i <= n; i++){
int val; scanf("%d", &val);
Insert(val);
if (i == ){ ans = val; }
else{
ans += min(abs(val - T[succ()].key), abs(val - T[prev()].key));
}
}
printf("%lld\n", ans);
}
//#ifdef LOCAL_TIME
// cout << "[Finished in " << clock() - start << " ms]" << endl;
//#endif
return ;
}

HYSBZ 1588 营业额统计的更多相关文章

  1. HYSBZ - 1588 营业额统计 (伸展树)

    题意:营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额.分析营 ...

  2. HYSBZ 1588 营业额统计 (Splay树)

    题意:给出一个公司每一天的营业额,求每天的最小波动值之和.该天的最小波动值= min { 绝对值| 该天以前某一天的营业额-该天的营业额 | }.第一天的最小波动值就是其自己. 思路:Splay伸展树 ...

  3. (HYSBZ)BZOJ 1588 营业额统计

    营业额统计 Time Limit: 5000MS   Memory Limit: 165888KB   64bit IO Format: %lld & %llu Description 营业额 ...

  4. BZOJ 1588 营业额统计

    Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成立以来每 ...

  5. BZOJ 1588 营业额统计 set

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1588 题目大意: 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交 ...

  6. bzoj 1588营业额统计(HNOI 2002)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1588 splay  bottom-up的数组实现. 题意就是给你一组数,求每个数与在其前面且与其最相 ...

  7. BZOJ 1588 营业额统计 Splay

    主要操作为Splay中插入节点,查找前驱和后继节点. 1: #include <cstdio> 2: #include <iostream> 3: #include <c ...

  8. [bzoj] 1588 营业额统计 || Splay板子题

    原题 给出一个n个数的数列ai ,对于第i个元素ai定义\(fi=min(|ai-aj|) (1<=j<i)\),f1=a1,求\(/sumfi\) Splay板子题. Splay讲解:h ...

  9. 营业额统计 HYSBZ - 1588

    营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营业额.分析营业情况 ...

随机推荐

  1. c#操作时间

    本年还剩下多少天 private string GetEndTime() { DateTime dt = DateTime.Now; DateTime startYear = DateTime.Now ...

  2. mybatis 的if else

    <update id="update" parameterType="XXX">         update XX set YY          ...

  3. 在Win7下使用sphinx-build建立开源软件文档

    最近想看看odoo的使用文档,在线看不方便,而且还没有提供离线文档下载,由于是开源项目,此项目托管在Github上,于是就有了想通过Github把文档git下来,可是git下来的文档是.rst文件,无 ...

  4. ios waxpatch lua语法

    Wax Lua 使用方法 说一下 Wax 的特点,它支持你在脚本里使用任何 OC 的类,同样也支持你创建一个类. 使用一个类时你会这样使用: 1 2 NSString -- Returns the N ...

  5. 修改searchbar 取消 字体 颜色

    UIButton *cancelButton; UIView *topView = self.searchDisplayController.searchBar.subviews[]; for (UI ...

  6. hibernate之处理视图

    近期,我去用hibernate去创建视图, 发现无法进立建立视图, 为啥? 个人去尝试去,却发现无法很好的完成, 因为hibernate的作用类似视图 后解决方案是: 1.用传统的方式去处理 2.写存 ...

  7. php 关联数据库的留言板练习

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. php 会话控制

    会话控制 HTTP协议,在TCP协议基础上的HTTP协议称为无状态协议 SESSION COOKIE SESSION特点:1.存储在服务器.2.每个使用者都会生成一个SESSION.3.有默认的过期时 ...

  9. 攻城狮在路上(肆)How tomcat works(三) 连接器:Connector

     在介绍中提到,Catalina中有两个主要的模块:连接器和容器.本章中你将会写一个可以创建更好的请求和响应对象的连接器,用来改进第2章中的程序.一个符合Servlet 2.3和2.4规范的连接器必须 ...

  10. oracle检查点队列(checkpoint queue)

    buffer cache CBC链 按地址链 LRU  干净buffer LRUW  脏buffer  按照冷热 checkpoint queue:链buffer,①链脏块②按buffer第一次脏的时 ...