题目链接: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. ajax 删除一条数据

    代码: 对这一段话的理解:先找到需要删除的节点,以及节点里的文本:用Ajax 发送请求,请求方式为POST ,请求内容为需要删除记录的文件,dataType定义数据类型Json,通常都是Json,da ...

  2. struts2拦截器+监听器 .

    一.拦截器是怎么实现: 实际上它是用Java中的动态代理来实现的 二.拦截器在Struts2中的应用 对于Struts2框架而言,正是大量的内置拦截器完成了大部分操作.像params拦截器将http请 ...

  3. 【XLL 框架库函数】 debugPrintf

    通过调用 Windows SDK 函数 OutputDebugStringA 在激活的调试器中输出字符串信息.如果应用程序没有调试器,那么系统调试器就会显示字符串.如果这两种调试器都没使用的话,deb ...

  4. Jquery 提示还可以输入的字数,将多余的字数截取掉

    js代码: $(function () { var counter = $("#divform textarea").val().length; //获取文本域的字符串长度 $( ...

  5. CentOS 7.0 部署 Django 到运行起来第一个web service

    最近在学习Python,今天发现Django如此强大的web框架,不得不来试一试. 1. 安装Python,官网建议用Python3:

  6. Linux将Shelll输出写入到文件

    &>  以覆盖的方式,写入文件 &>> 将输出追加到文件 将命令的正确输出与错误输出都放入文件. /dev/null,垃圾箱. 将无用输出放入垃圾箱. 命令>& ...

  7. iosTest

    NSString * url = @"http://192.168.0.11:8000/InterfaceApp/Login?UserName=15995858188&Passwor ...

  8. 20145206邹京儒《Java程序设计》第8周学习总结

    20145206 <Java程序设计>第8周学习总结 教材学习内容总结 第十四章 NIO与NIO2 14.1 认识NIO NIO使用频道(Channel)来衔接数据节点,在处理数据时,NI ...

  9. poj 1837

    题目链接:http://poj.org/problem?id=1837 题目大意: 有一个天平,左臂右臂各长15,然后给出n,m,n代表有几个挂钩,挂钩给出负数代表在左臂的距离,正数则在右臂m代表有m ...

  10. python中统计列表各个元素的个数