P4331 [BalticOI 2004]Sequence 数字序列

给定一个序列整数a1,a2,a3,…,an−1,ana_1, a_2, a_3, \dots, a_{n - 1}, a_na1​,a2​,a3​,…,an−1​,an​,要找一个整数序列bbb,满足b1<b2<b3<⋯<bn−1<bnb_1 < b_2 < b_3< \dots< b_{n - 1}< b_{n}b1​<b2​<b3​<⋯<bn−1​<bn​,使∑i=1n∣ai−bi∣\sum\limits_{i = 1} ^{n} \mid a_i - b_i \midi=1∑n​∣ai​−bi​∣最小。

先对aia_iai​整体减去iii,也就是ai=ai−ia_i = a_i - iai​=ai​−i,最后我们再对答案加上对应的做标,这个问题就变成找一个非递减序列了,b1≤b2≤⋯≤bnb_1 \leq b_2 \leq \dots \leq b_{n}b1​≤b2​≤⋯≤bn​。

考虑两种特殊情况:

特殊情况一般化:

我们可以考虑把整个序列分成m,(m≤n)m, (m \leq n)m,(m≤n)段,对每段特殊地考虑,有区间长度为一的时候,是符合第一个条件的可把区间答案设置为bib_ibi​。

对于相邻的区间,如果满足ans[i−1]≤ans[i]ans[i - 1] \leq ans[i]ans[i−1]≤ans[i],显然我们可以不做改变,即这就是一个合法的且最优的答案。

如果相邻的区间存在ans[i−1]≥ans[i]ans[i - 1] \geq ans[i]ans[i−1]≥ans[i],那么我们就要对这两个区间做一定的变化了,由②可知,我们选这两段区间的中位数可使改变后的答案也是最优的。

根据上述可知,我们需要快速合并一段区间,并且需要快速求出这段合并的区间的中位数,考虑用可并堆实现即可。

#include <bits/stdc++.h>using namespace std;const int N = 1e6 + 10;int ls[N], rs[N], value[N], dis[N];int root[N], sz[N], l[N], r[N], ans[N], n, cnt;int merge(int x, int y) {if (!x || !y) {return x | y;}if (value[x] < value[y]) {swap(x, y);}rs[x] = merge(rs[x], y);if (dis[ls[x]] < dis[rs[x]]) {swap(ls[x], rs[x]);}dis[x] = dis[rs[x]] + 1;return x;
}int main() {// freopen("in.txt", "r", stdin);// freopen("out.txt", "w", stdout);scanf("%d", &n);for (int i = 1; i <= n; i++) {scanf("%d", &value[i]);value[i] -= i;}for (int i = 1; i <= n; i++) {cnt++;root[cnt] = i, l[cnt] = i, r[cnt] = i, sz[cnt] = 1, ans[cnt] = value[i];while (cnt > 1 && ans[cnt - 1] > ans[cnt]) {cnt--;root[cnt] = merge(root[cnt], root[cnt + 1]);sz[cnt] += sz[cnt + 1];r[cnt] = r[cnt + 1];while (sz[cnt] > (r[cnt] - l[cnt] + 3) / 2) {sz[cnt]--;root[cnt] = merge(ls[root[cnt]], rs[root[cnt]]);}ans[cnt] = value[root[cnt]];}}long long res = 0;for (int i = 1; i <= cnt; i++) {for (int j = l[i]; j <= r[i]; j++) {res += abs(value[j] - ans[i]);}}printf("%lld\n", res);for (int i = 1; i <= cnt; i++) {for (int j = l[i]; j <= r[i]; j++) {printf("%d%c", ans[i] + j, j == n ? '\n' : ' ');}}return 0;
}

P4331 [BalticOI 2004]Sequence 数字序列(左偏树)相关推荐

  1. 左偏树(可并堆)初步及其应用

    作者:hsez_yyh 链接:左偏树(可并堆)初步及其应用_hsez_yyh的博客-CSDN博客 来源:湖北省黄石二中信息竞赛组        著作权归作者所有.商业转载请联系作者获得授权,非商业转载 ...

  2. P4331-[BalticOI2004]Sequence数字序列【左偏树】

    正题 题目链接:https://www.luogu.com.cn/problem/P4331 题目大意 给出一个序列aaa,求一个单调上升的序列bbb使得∑i=1n∣ai−bi∣\sum_{i=1}^ ...

  3. 一篇讲左偏树的好文章~

    传送门:http://blog.csdn.net/iaccepted/article/details/6748038 二.左偏树的定义和性质.............................. ...

  4. 《程序设计解题策略》——1.6 利用左偏树实现优先队列的合并

    本节书摘来自华章计算机<程序设计解题策略>一书中的第1章,第1.6节,作者:吴永辉 王建德 更多章节内容可以访问云栖社区"华章计算机"公众号查看. 1.6 利用左偏树实 ...

  5. 【学习笔记】浅谈短小可爱的左偏树(可并堆)

    文章目录 左偏树 左偏树的合并(merge)操作 例题 罗马游戏 [Apio2012]dispatching [JLOI2015]城池攻占 [Baltic2004]sequence 左偏树 左偏树是一 ...

  6. [2018.12.6]左偏树

    其实NOIp之前就学会了...结果咕到了现在... 我们都知道堆.但是很少有人会手写堆.因为我们有STL,而且手写堆码量不小(据说是吧?没写过). 而且堆的\(Merge\)操作又慢又麻烦. 于是就有 ...

  7. 左偏树初步学习 洛谷P3377

    玩的有点多......睡的有点少... 左偏树是一种支持O(logn)的时间复杂度内进行合并的堆式数据结构. 定义: 外结点:左儿子或者右儿子是空结点的结点 距离:一个结点x的距离disx定义为其子树 ...

  8. 可并堆——左偏树 Leftist Heap

    今天学习了左偏树,这是一个好理解而且好写的数据结构,和二叉堆一样可以在O(1)时间内取出优先级最高的值,O(logn)时间内删除优先级最高的值,不同的是如果要合并两个堆那么二叉堆就只能跪了.而左偏树能 ...

  9. Monkey King(左偏树 可并堆)

    我们知道如果要我们给一个序列排序,按照某种大小顺序关系,我们很容易想到优先队列,的确很方便,但是优先队列也有解决不了的问题,当题目要求你把两个优先队列合并的时候,这就实现不了了 优先队列只有插入 删除 ...

最新文章

  1. tensorflow2caffe(1) : caffemodel解析,caffemodel里面到底记录了什么?
  2. 英雄联盟手游主播否认部分英雄后期的作用,难道阿卡丽没未来?
  3. CentOS6.5下搭建SVN服务器
  4. Java反射xml数据类
  5. oracle修改字符集
  6. 梨花带雨播放器程序开源版本
  7. android应用程序的生命周期,Android应用程序的生命周期.doc
  8. goldendb基于mysql_中兴通讯GoldenDB在中信银行信用卡核心应用实践
  9. PostgreSQL备份之omniPITR
  10. 【Elasticsearch】Elasticsearch 集群健康值黄色 解决方案 或者 分片 未分配
  11. Python进阶(十三) os、random、time等标准库
  12. 苹果mac效率软件:alfred 4
  13. LA 3268 号码簿分组(最大流+二分)
  14. Qt5中this application has requested the runtime to terminate it in an unusual way 无法运行问题的解决
  15. 百度网页注册HTML代码
  16. 拼多多商品详情如何获取呢?进来手把手教你
  17. linux 信号sigabrt,關於Linux中的SIGABRT信號
  18. 实现极致节能,维谛技术(Vertiv)有哪些特殊技能?
  19. 打印机与电脑文件服务器,电脑无法共享局域网打印机和文件的解决方法
  20. 复旦计算机课程谁的好,复旦大学计算机研究生导师有哪些

热门文章

  1. python闭环最短路径_深度学习经典算法 | 蚁群算法解析
  2. 5.7.21mysql数据库_【数据库】mysql5.7.21 winx64安装配置图文分享
  3. js监听多个事件_JavaScript中的事件与异常捕获解析
  4. 奇妙的曲线--希尔伯特曲线
  5. 为什么每个理发店门口都有彩色的柱子?你不知道吧
  6. 我居然从一只猫身上学到了斐波那契数列
  7. 如何简单形象又有趣地讲解神经网络是什么?
  8. 猴子偷桃php代码,C++实现猴子吃桃的示例代码
  9. android led闪烁功能,如何在Android应用层中制作一个LED指示灯效果
  10. html assign无效,Object.assign的一些用法