博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
TYVJ-1185 营业额统计 Splay
阅读量:5945 次
发布时间:2019-06-19

本文共 2854 字,大约阅读时间需要 9 分钟。

该题应该有很多的解法,想过用二分查找,但是排序操作的复杂度让我们伤不起。这里用Splay来实现是很方便的。首先插入一个点,即第一个点,然后再依次用二叉排序树方式插入当前点,再把该点旋转到根部(这样方便我们找前驱和后继,否则需要中序遍历整棵树来确定),再在存在前驱和后继的情况下寻找前驱和后继。接下来就很好办了。

代码如下:

#include 
#include
#include
#include
#define L(x) tree[x].ch[0]#define R(x) tree[x].ch[1]#define INF 0x3ffffff#define MAXN 33000using namespace std;int N, seq[MAXN], que[MAXN], front, rt;struct Node{ int v, ch[2], fa; void New(int v, int fa) { this->v = v, this->fa = fa; ch[0] = ch[1] = 0; }}tree[MAXN];void init(){ for (int i = 0; i < MAXN; ++i) { que[i] = i; } rt = que[++front]; tree[rt].New(seq[1], 0);}int insert(int &rt, int &num, int fa) // 引用仅仅为了速度考虑{ if (rt == 0) { // 说明这个节点是待填充的 int x = que[++front]; rt = x; tree[x].New(num, fa); return x; } if (num > tree[rt].v) { return insert(R(rt), num, rt); } else { return insert(L(rt), num, rt); }}void rotate(int x, int f){ int y = tree[x].fa, z = tree[y].fa; tree[y].ch[!f] = tree[x].ch[f]; tree[ tree[y].ch[!f] ].fa = y; tree[x].ch[f] = y; tree[y].fa = x; tree[x].fa = z; if (z) { tree[z].ch[ R(z) == y ] = x; }}void splay(int x, int obj){ int y, z; while (tree[x].fa != obj) { y = tree[x].fa, z = tree[y].fa; if (z == obj) { rotate(x, L(y) == x); } else if (x == L(y) && y == L(z)) { rotate(y, 1), rotate(x, 1); } else if (x == R(y) && y == R(z)) { rotate(y, 0), rotate(x, 0); } else if (x == R(y) && y == L(z)) { rotate(x, 0), rotate(x, 1); } else { rotate(x, 1), rotate(x, 0); } } if (obj == 0) { rt = x; }}int findPre(int rt, int num){ if (R(rt) == 0) { return tree[rt].v; } else { return findPre(R(rt), num); }}int findNext(int rt){ if (L(rt) == 0) { return tree[rt].v; } else { return findNext(L(rt)); }}int main(){ int pos, ans, pre, next, sum; while (scanf("%d", &N) == 1) { sum = 0; for (int i = 1; i <= N; ++i) { scanf("%d", &seq[i]); } init(); if (N >= 1) { sum += seq[1]; } for (int i = 1; i <= N; ++i) { ans = INF; pos = insert(rt, seq[i], tree[rt].fa); splay(pos, 0); // 这个操作会将pos节点变成根节点 if (L(rt)) { pre = findPre(L(rt), seq[i]); ans = abs(seq[i] - pre); } if (R(rt)) { next = findNext(R(rt)); ans = min(abs(next - seq[i]), ans); } sum += ans; } printf("%d\n", sum); } return 0;}

转载于:https://www.cnblogs.com/Lyush/archive/2012/06/17/2552583.html

你可能感兴趣的文章
微服务+:服务契约治理
查看>>
save
查看>>
Android DrawLayout + ListView 的使用(一)
查看>>
clear session on close of browser jsp
查看>>
关于吃掉物理的二次聚合无法实现的需要之旁门左道实现法
查看>>
mysql出现unblock with 'mysqladmin flush-hosts'
查看>>
oracle exp/imp命令详解
查看>>
开发安全的 API 所需要核对的清单
查看>>
Mycat源码中的单例模式
查看>>
WPF Dispatcher介绍
查看>>
fiddler展示serverIP方法
查看>>
已释放的栈内存
查看>>
Android网络之数据解析----SAX方式解析XML数据
查看>>
Java递归列出所有文件和文件夹
查看>>
[关于SQL]查询成绩都大于80分的学生
查看>>
Delphi(Tuxedo,BDE,ADO)三合一数据集组件HsTxQuery
查看>>
LeetCode - Longest Common Prefix
查看>>
Android图片处理
查看>>
2015年第21本:万万没想到,用理工科思维理解世界
查看>>
大家谈谈公司里的项目经理角色及职责都是干什么的?
查看>>