题目链接在这里~

对于序列\(\{a\}\),把每一个\(a_i\)减去一个\(i\),得到\(\{a'\}\)序列\(\{b\}\)同理。

因为\(b_1<b_2<...<b_n\),故\(b_1'\leqslant b_2'\leqslant ... \leqslant b_n'\)

又\(a_i-b_i\)不变,故新问题与原问题等价。

因此我们就把问题就转化成了一个单调不下降序列。

我们将\(\{a_1, a_2, ..., a_m\}\)序列分成两段\(a_1...a_n\)\(a_{n+1}...a_m\)

假设\(b_1=b_2=...=b_n=u,b_{n+1}=b_{n+2}=... = b_{m}=v\)

则这个问题就变成了经典的邮递员问题,即货仓选址问题。

分类讨论:

  1. \(u\leqslant v\),则前半段取\(u\),后半段取\(v\)即为最优解。
  2. \(u > v\),则\(\frac{u+v}{2}\)(\(u,v\)的中位数)为最优解,用左偏树实现。

    得到了中位数之后还需要下压.

    那么其中有两种情况. 奇数个数的中位数, 和偶数个数的中位数(为了方便用cost表示a和b的差值的绝对值):

    1 奇数个数的中位数的时候就只能选这个中位数, 然后无论再往上或者往下压的cost都得增加至少1. 那么如果这个中位数的解如果不小于再往前一段的解的话, 则可以结束. 若小于, 则需要再往前合并找中位数循环直到结束

    2 偶数个数的中位数. 那么可以在中间2个数之间上下浮动:

    a. 如果再往前一段的解在这2个数之间, 则取再往前一段的解即可. 否则如果往上虽然不增加cost但是还能下压, 往下的话就得继续合并前一段增加cost.

    b. 如果再往前一段的解小于这个区间, 则直接选这2个数里面小的即可

    c. 如果再往前一段的解大于这个区间, 则还是选这2个数里面小的, 然后再往之前合并

code

#include <bits/stdc++.h>

typedef long long ll;

using namespace std;

const int N = 1e6 + 10;

int n, v[N], dist[N], l[N], r[N], ans[N], tt;
ll res; struct Segment{int end, root, size;}stk[N]; int merge(int x, int y)
{
if (!x || !y) return x + y;
if (v[x] < v[y]) swap(x, y);
r[x] = merge(r[x], y);
if (dist[r[x]] > dist[l[x]]) swap(r[x], l[x]);
dist[x] = dist[r[x]] + 1;
return x;
} int pop(int x){return merge(l[x], r[x]);} int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i ++ )
{
scanf("%d", &v[i]);
v[i] -= i;
} for (int i = 1; i <= n; i ++ )
{
auto cur = Segment({i, i, 1});
dist[i] = 1;
while (tt && v[cur.root] < v[stk[tt].root])
{
cur.root = merge(cur.root, stk[tt].root);
if (cur.size % 2 && stk[tt].size % 2) cur.root = pop(cur.root);
cur.size += stk[tt].size, tt -- ;
}
stk[ ++ tt] = cur;
} for (int i = 1, j = 1; i <= tt; i ++ ) while (j <= stk[i].end) ans[j ++ ] = v[stk[i].root]; for (int i = 1; i <= n; i ++ ) res += abs(v[i] - ans[i]);
printf("%lld\n", res);
for (int i = 1; i <= n; i ++ ) printf("%d ", ans[i] + i); return 0;
}

BalticOI 2004 Sequence 题解的更多相关文章

  1. luogu 4331 [BalticOI 2004]Sequence 数字序列

    LINK:数字序列 这是一道论文题 我去看了一眼论文鸽的论文. 发现讲的还算能懂.可并堆的操作也讲的比较清晰. 对于这道题首先有一个小trick 我们给a数组全部减去其对应的下标这样我们求出来的b数组 ...

  2. 【CF486E】LIS of Sequence题解

    [CF486E]LIS of Sequence题解 题目链接 题意: 给你一个长度为n的序列a1,a2,...,an,你需要把这n个元素分成三类:1,2,3: 1:所有的最长上升子序列都不包含这个元素 ...

  3. 题解-BOI 2004 Sequence

    Problem bzoj & Luogu 题目大意: 给定序列\(\{a_i\}\),求一个严格递增序列\(\{b_i\}\),使得\(\sum \bigl |a_i-b_i\bigr|\)最 ...

  4. CF3D Least Cost Bracket Sequence 题解

    题目 This is yet another problem on regular bracket sequences. A bracket sequence is called regular, i ...

  5. POJ3581:Sequence——题解

    http://poj.org/problem?id=3581 给一串数,将其分成三个区间并且颠倒这三个区间,使得新数列字典序最小. 参考:http://blog.csdn.net/libin56842 ...

  6. BZOJ4355:Play with sequence——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4355 维护一个长度为N的序列a,现在有三种操作: 1)给出参数U,V,C,将a[U],a[U+1] ...

  7. Pop Sequence 题解

    Pop Sequence(PAT) https://www.nowcoder.com/pat/5/problem/4090 前言: PAT上一道Stack的应用题,简化版的有<信息学一本通·普及 ...

  8. CF524F And Yet Another Bracket Sequence 题解

    题目链接 算法:后缀数组+ST表+贪心   各路题解都没怎么看懂,只会常数巨大的后缀数组+ST表,最大点用时 \(4s\), 刚好可以过... 确定合法序列长度   首先一个括号序列是合法的必须满足以 ...

  9. 洛谷 P6573 [BalticOI 2017] Toll 题解

    Link 算是回归OI后第一道自己写的题(考CSP的时候可没回归) 写篇题解纪念一下 题目大意: \(n\) 个点,\(m\) 条单向边,每条边的两端点 \(x\),\(y\)必定满足 \(\left ...

  10. Codeforces 486E LIS of Sequence 题解

    题目大意: 一个序列,问其中每一个元素是否为所有最长上升子序列中的元素或是几个但不是所有最长上升子序列中的元素或一个最长上升子序列都不是. 思路: 求以每一个元素为开头和结尾的最长上升子序列长度,若两 ...

随机推荐

  1. SpringBoot(七) - Redis 缓存

    1.五大基本数据类型和操作 1.1 字符串-string 命令 说明 set key value 如果key还没有,那就可以添加,如果key已经存在了,那会覆盖原有key的值 get key 如果ke ...

  2. Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test (default-test) on project StuMavenDemo1: There are test failures.

    Maven使用Test的时候出现 Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test ( ...

  3. 2流高手速成记(之四):SpringBoot整合redis及mongodb

    最近很忙,好不容易才抽出了时间,咱们接上回 上次我们主要讲了如何通过SpringBoot快速集成mybatis/mybatis-plus,以实现业务交互中的数据持久化,而这一切都是基于关系型数据库(S ...

  4. .net core 读取appsettings.json 文件中文乱码的问题

    解决办法:设置高级保存选项 第一步:在工具栏找到自定义选项 第二步:添加高级保存选项Advanced save options 第三步:在Appsettings.json页面操作

  5. iptables规则查询

    iptables规则查询 之前在iptables的概念中已经提到过,在实际操作iptables的过程中,是以"表"作为操作入口的,如果你经常操作关系型数据库,那么当你听到" ...

  6. 前后端分离项目(十):实现"改"功能(前后端)

    好家伙,本篇介绍如何实现"改" 我们先来看看效果吧  (这可不是假数据哟,这是真数据哟)  (忘记录鼠标了,这里是点了一下刷新) First Of All 我们依旧先来理一下思路: ...

  7. Element基本组件

    Element按钮组件: <el-row> <el-button>默认按钮</el-button> <el-button type="primary ...

  8. 【Azure 事件中心】Event Hub 无法连接,出现 Did not observe any item or terminal signal within 60000ms in 'flatMapMany' 的错误消息

    问题描述 使用Java SDK连接Azure Event Hub,一直出现 java.util.concurrent.TimeoutException 异常, 消息为:java.util.concur ...

  9. 《ASP.NET Core技术内幕与项目实战》精简集-目录

    本系列是杨中科2022年最新作品<ASP.NET Core技术内幕与项目实战>及B站配套视频(强插点赞)的精简集,是一个读书笔记.总结和提炼了主要知识点,遵守代码优先原则,以利于快速复习和 ...

  10. Vue实现离开页面二次确认

    在项目开发中遇到用户编辑内容后未保存推出编辑页面时需要提示用户"当前数据未保存,是否退出",实际开发中利用window.onbeforeunload方法与vue.$on方法在upd ...