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

本文共 2762 字,大约阅读时间需要 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;}

转载地址:http://jkrma.baihongyu.com/

你可能感兴趣的文章
css知多少(11)——position
查看>>
【Spring】定时任务详解实例-@Scheduled
查看>>
先有的资源,能看的速度看,不能看的,抽时间看。说不定那天就真的打不开了(转)...
查看>>
[20161028]rman与filesperset=1.txt
查看>>
哪些领域适合开发微信小程序
查看>>
谁说数据库防火墙风险大?可能你还不知道应用关联防护
查看>>
ASP.NET Core应用针对静态文件请求的处理[2]: 条件请求与区间请求
查看>>
怎样做一个企业?尤其是在这个互联网时代
查看>>
DVNA:Node.js打造的开源攻防平台
查看>>
17个案例带你3分钟搞定Linux正则表达式
查看>>
Java 8 比较器:如何对 List 排序
查看>>
苹果是否步思科后尘折戟中国
查看>>
漏洞预警!微软曝光震网三代漏洞,隔离网面临重大危机
查看>>
协鑫集成第二批1000台E-KwBe光伏储能设备即将启运澳洲
查看>>
爱立信物联网广州路演
查看>>
云计算企业业绩分化明显 9家上市公司中期预喜
查看>>
《VMware Virtual SAN权威指南(原书第2版)》一3.5 可能发生的网络配置问题
查看>>
SK电讯发布Q2财报 净利润同比下降26.9%
查看>>
零售品牌如何驾驭大数据主导商业决策?
查看>>
经济模式UPS在数据中心的应用(上)
查看>>