BZOJ 1588:营业额统计(Splay)
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)的更多相关文章
- BZOJ 1588 营业额统计 Splay
主要操作为Splay中插入节点,查找前驱和后继节点. 1: #include <cstdio> 2: #include <iostream> 3: #include <c ...
- [bzoj] 1588 营业额统计 || Splay板子题
原题 给出一个n个数的数列ai ,对于第i个元素ai定义\(fi=min(|ai-aj|) (1<=j<i)\),f1=a1,求\(/sumfi\) Splay板子题. Splay讲解:h ...
- BZOJ 1588 营业额统计
Description 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成立以来每 ...
- (HYSBZ)BZOJ 1588 营业额统计
营业额统计 Time Limit: 5000MS Memory Limit: 165888KB 64bit IO Format: %lld & %llu Description 营业额 ...
- BZOJ 1588 营业额统计 set
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1588 题目大意: 营业额统计 Tiger最近被公司升任为营业部经理,他上任后接受公司交 ...
- bzoj 1588营业额统计(HNOI 2002)
http://www.lydsy.com/JudgeOnline/problem.php?id=1588 splay bottom-up的数组实现. 题意就是给你一组数,求每个数与在其前面且与其最相 ...
- Bzoj 1588: [HNOI2002]营业额统计(splay)
1588: [HNOI2002]营业额统计 Time Limit: 5 Sec Memory Limit: 162 MB Description 营业额统计 Tiger最近被公司升任为营业部经理,他上 ...
- 1588: [HNOI2002]营业额统计 (splay tree)
1588: [HNOI2002]营业额统计 Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 5783 Solved: 1859[Submit][Stat ...
- 【BZOJ-1588】营业额统计 Splay
1588: [HNOI2002]营业额统计 Time Limit: 5 Sec Memory Limit: 162 MBSubmit: 12485 Solved: 4508[Submit][Sta ...
- [HNOI2002]营业额统计 Splay tree入门题
题目连接:http://www.lydsy.com/JudgeOnline/problem.php?id=1588 1588: [HNOI2002]营业额统计 Time Limit: 5 Sec ...
随机推荐
- 面向对象编程(九)——面向对象三大特性之继承以及重写、Object类的介绍
面向对象三大特性 面向对象三大特征:继承 :封装/隐藏 :多态(为了适应需求的多种变化,使代码变得更加通用!) 封装:主要实现了隐藏细节,对用户提供访问接口,无需关心方法的具体实现. 继承:很好的实现 ...
- Java 线程池的介绍以及工作原理
在什么情况下使用线程池? 1.单个任务处理的时间比较短 2.将需处理的任务的数量大 使用线程池的好处: 1. 降低资源消耗: 通过重复利用已创建的线程降低线程创建和销毁造成的消耗.2. 提高响应速度: ...
- shell中&&和||的使用方法_转
shell中&&和||的使用方法 &&运算符: command1 && command2 &&左边的命令(命令1)返回真(即返 ...
- 一个四叉树Demo学习
程序代码: http://www.codeproject.com/Articles/30535/A-Simple-QuadTree-Implementation-in-C 四叉树: using Sys ...
- 在centos安装docker
关闭防火墙 iptables -L systemctl disable firewalld.service systemctl stop firewalld.service 配置代理太麻烦了,建议使用 ...
- 【转】Java多线程编程中易混淆的3个关键字( volatile、ThreadLocal、synchronized)总结
概述 最近在看<ThinKing In Java>,看到多线程章节时觉得有一些概念比较容易混淆有必要总结一下,虽然都不是新的东西,不过还是蛮重要,很基本的,在开发或阅读源码中经常会遇到,在 ...
- linux:磁盘的分割、检验、格式化与挂载
新增一颗磁碟: 1.对磁碟进行分割,以建立可用的partition 2.对该分割槽partition进行格式化(format),以建立系统可用的filesystem 3.若要仔细点,可对刚刚建立的fi ...
- Three.js基础探寻十——动画
本篇将介绍如果使用Three.js进行动态画面的渲染.此外,将会介绍一个Three.js作者写的另外一个库stat.js,用来观测每秒帧数(FPS). 1.实现动画效果 1.1 动画原理 对于Thre ...
- 一个新人对JavaScript的内容简单介绍
JavaScript 1.基本的数据类型:字符串 小数 整数 时间日期 布尔型等. 2.变量: JS定义变量通通都是用var开头,var里面可以放任何东西(如:小数,整数,字符串,时间日期等等 ...
- PHP和JS实现多按钮提交表单
JS: <html> <head> <script> function submitit1() //交由程序1处理 { document.myForm.action ...