http://www.lydsy.com/JudgeOnline/problem.php?id=1588

题意:中文题意。

思路:每一个点每一个点插入Splay,然后插入新的一个点之后,查这个节点的前驱和后继,即左子树最右边的点和右子树最左边的点。然后再从两个点中取个差值较小的就是答案了。要注意Rotate的时候一些细节(要给 rt 的父亲的父亲更新其孩子的值),还有Splay的细节:如果 rt 和 父节点都是要旋转相同方向,应该先旋转父亲节点再旋 rt,如果旋转不同方向就都是旋 rt。

 #include <cstdio>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
#include <queue>
#include <vector>
using namespace std;
#define INF 0x7fffffff
#define N 40000
struct node
{
int val, fa, son[]; // val是节点权值,fa是父亲,son[0]是左儿子, son[1]是右儿子
}tree[N];
int cnt; // 节点数 void new_node(int f, int w, int kind)
{
cnt++;
memset(tree[cnt].son, , sizeof(tree[cnt].son));
tree[cnt].val = w;
tree[cnt].fa = f;
tree[f].son[kind] = cnt;
} void Rotate(int rt, int kind) // 旋转操作要注意更新 rt 的父亲的父亲的儿子的值
{
int y = tree[rt].fa;
tree[y].son[kind^] = tree[rt].son[kind];
if(tree[rt].son[kind] != ) tree[tree[rt].son[kind]].fa = y;
tree[rt].fa = tree[y].fa;
int z = tree[rt].fa;
if(tree[z].son[] == y) tree[z].son[] = rt; // 就是这里
else tree[z].son[] = rt;
tree[rt].son[kind] = y;
tree[y].fa = rt;
} void Splay(int rt, int goal)
{
if(tree[rt].fa == goal) return ;
while(tree[rt].fa != goal) {
int y = tree[rt].fa;
int z = tree[y].fa;
int kind1 = rt == tree[y].son[] ? : ;
int kind2 = y == tree[z].son[] ? : ;
if(z == goal) {
Rotate(rt, kind1);
} else {
if(kind1 == kind2) { // 连续左旋或者右旋
Rotate(y, kind2);
} else {
Rotate(rt, kind1); // 先左后右或者先右后左
}
Rotate(rt, kind2);
}
}
} void Insert(int rt, int fa, int val, int kind)
{
if(rt == ) {
new_node(fa, val, kind);
return ;
}
if(tree[rt].val >= val) Insert(tree[rt].son[], rt, val, );
else Insert(tree[rt].son[], rt, val, );
} int Find(int rt, int kind)
{
if(tree[rt].son[kind] == ) return rt; // 查先驱和后继节点
Find(tree[rt].son[kind], kind);
} int main()
{
int n;
while(~scanf("%d", &n)) {
long long ans = ;
cnt = ;
for(int i = ; i <= n; i++) {
int x;
scanf("%d", &x);
if(i == ) {
new_node(, x, );
ans += x;
} else {
Insert(cnt, , x, );
Splay(cnt, );
int pre = , suf = ;
pre = Find(tree[cnt].son[], );
suf = Find(tree[cnt].son[], );
int prev = INF, sufv = INF;
if(pre != ) prev = tree[pre].val;
if(suf != ) sufv = tree[suf].val;
ans += min(abs(x - prev), abs(x - sufv));
}
}
printf("%lld\n", ans);
}
return ;
}

BZOJ 1588:营业额统计(Splay)的更多相关文章

  1. BZOJ 1588 营业额统计 Splay

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

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

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

  3. BZOJ 1588 营业额统计

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

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

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

  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: [HNOI2002]营业额统计(splay)

    1588: [HNOI2002]营业额统计 Time Limit: 5 Sec Memory Limit: 162 MB Description 营业额统计 Tiger最近被公司升任为营业部经理,他上 ...

  8. 1588: [HNOI2002]营业额统计 (splay tree)

    1588: [HNOI2002]营业额统计 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 5783  Solved: 1859[Submit][Stat ...

  9. 【BZOJ-1588】营业额统计 Splay

    1588: [HNOI2002]营业额统计 Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 12485  Solved: 4508[Submit][Sta ...

  10. [HNOI2002]营业额统计 Splay tree入门题

    题目连接:http://www.lydsy.com/JudgeOnline/problem.php?id=1588 1588: [HNOI2002]营业额统计 Time Limit: 5 Sec   ...

随机推荐

  1. Google File System翻译(转)

    摘要 我们设计实现了google文件系统,一个面向大规模分布式数据密集性应用的可扩展分布式文件系统.它运行在廉价的商品化硬件上提供容错功能,为大量的客户端提供高的整体性能. 尽管与现有的分布式文件系统 ...

  2. LuaExpat笔记

    xml xml是一种格式化数据交换语言, 适用于在网络上不同应用会话. http://www.xml.com/pub/a/98/10/guide0.html exPat 一种C语言实现的 xml 文档 ...

  3. bootstrap ace treeview树表

    html部分 <div class="widget-main padding-8" style="height:400px;overflow-y: scroll;& ...

  4. JAVA NIO系列(三) Buffer 解读

    缓冲区分类 NIO中的buffer用于和通道交互,数据是从通道读入缓冲区,从缓冲区中写入通道的.Buffer就像一个数组,可以保存多个类型相同的数据.每种基本数据类型都有对应的Buffer类: 缓冲区 ...

  5. span和div的区别

    <span> 在CSS定义中属于一个行内元素,在行内定义一个区域,也就是一行内可以被 <span> 划分成好几个区域,从而实现某种特定效果. <span> 本身没有 ...

  6. VS的基本学习

    2016.4.11  下午 一.数据类型 1.基本数据类型 注:字节:例{10221021  8位数为一个字节    8b=1B} 1).整形(整数) ① short(比Int短   Int16){2 ...

  7. JetBrains公司介绍(Java、Python、PHP、Ruby、前端和代码测试与重构的IDE)

    JetBrains JetBrains是一家捷克的软件开发公司,该公司位于捷克的布拉格,并在俄国的圣彼得堡及美国麻州波士顿都设有办公室,该公司最为人所熟知的产品是Java编程语言开发撰写时所用的集成开 ...

  8. ini,config文件的读取修改

    修改ini配置文件 // 声明INI文件的写操作函数 WritePrivateProfileString() [System.Runtime.InteropServices.DllImport(&qu ...

  9. WEB-INF/views/menu/list.jsp (line: 26, column: 58) equal symbol expected

    根本原因是由于单引号和双引号的混乱使用导致的. 解决办法: 将双引号里面的双引号改成单引号: 单引号里面的双引号该成单引号. 我的问题好像又不是这样的,<c:forEach var=" ...

  10. struts_23_xwork校验器列表使用例子

    required 必填校验器 <field-validator type="required"> <message>性别不能为空!</message& ...