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. API文档的阅读

    API ——Application Programming Interface(应用程序编程接口) API是应用程序接口的意思,API是Java提供的基本编程接口,当使用Java语言进行编程时,不可能 ...

  2. 用仿ActionScript的语法来编写html5——第七篇,自定义按钮

    第七篇,自定义按钮这次弄个简单点的,自定义按钮.其实,有了前面所定义的LSprite,LBitmap等类,定义按钮就很方便了.下面是添加按钮的代码, function gameInit(event){ ...

  3. LIS 最长递增子序列

    一.最长公共子序列 经典的动态规划问题,大概的陈述如下: 给定两个序列a1,a2,a3,a4,a5,a6......和b1,b2,b3,b4,b5,b6.......,要求这样的序列使得c同时是这两个 ...

  4. 不等高cell的搭建(一)

    一.界面搭建   1.确定开发模式      如果界面是固定的,可以用xib      界面的一些内容不固定,就用纯代码      cell用什么方式去开发(我们采用纯代码和xib结合的方式)   2 ...

  5. Effective C++ 1.让自己习惯C++

    //条款01:视C++为一个语言联邦 // 1:C++主要包含的语言为: // A:C.说到底C++仍然以C为基础.区块(blocks).语句.预处理器.内置数据类型.数组.指针等均来自于C.许多时候 ...

  6. DIY小能手|别买电动滑板车了,咱做一台吧

    !! http://www.shoudian.org/thread-316111-1-1.html http://www.jiequer.com/html/news/xinpin/2014/1218/ ...

  7. JSP数据交互习题错误总结

    1:如果注册完页面有中文字符需要在提交后的页面显示注册信息,切记先把接受到的request的编码方式改为中文:request.setCharacterEncoding("utf-8" ...

  8. asp,asp.net 以表格输出excel,数据默认科学计数的解决办法

    关键字:  style="vnd.ms-excel.numberformat:@" 问题:在用table仿excel生成中经常遇到类似于身份证的长整数类型excel默认当成科学计数 ...

  9. php 警告

    php.ini error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT error_log = /var/log/php-fpm/php ...

  10. 刚刚学了循环,1到n的求和与阶乘

    //求和 int a = Convert.ToInt32(Console.ReadLine()); int c = 0; for (int b = 0; b <= a; b++) { c = c ...