题面描述

给定整数数组$a_1,a_2,a_3...a_n$,求递增数组$b_1,b_2,b_3...b_n$

使得$|a_1 - b_1| + |a_2 - b_2| + ... + |a_n - b_n|$最大

吐槽:

这道题不是人能想出来的,太神了

很有收获?$or\; not\;?$

题解:

考虑$b$数组严格递增这个条件过于苛刻,期望$b$数组不严格递增

那么,由于$b_1 < b_2 < ... < b_n$,有$b_1 - 1 \leq b_2 - 2 ... \leq b_n - n$

我们不妨考虑新的$b'_i = b_i - i$

在$b'_i$对$a'_i = a_i - i$取到最优时,$b_i$同时对$a_i$取到最优

这时,$b‘_i$就可以相等了

两个性质

1. 对于$a'_1 \leq a'_2 \leq ... \leq a'_n$,我们取$b'i = a'i$最优

2. 对于$a'_1 \geq a'_2 \geq ... \geq a'_n$,我们取$b'i$为中位数最优

并且由于$b'_i$相等,$a'_1, a'_2...a'_n$可以任意的排列

因此,我们不妨假设已经处理好了前$i - 1$个数,正要加入第$i$个数

我们假设维护出来的$b'_i$相同的并成一个区间,$b'_i$取这个区间的中位数

对于$a'_i > b'_{i - 1}$,取$b'_i = a'_i$时,相等于递增序列

否则$a'_i < b'_{i - 1}$,我们把$i$并入$b'_{i - 1}$,得到新的中位数(因为顺序任意,所以怎么合都没问题),并继续检查

那么,我们要做的事其实就是

1. 快速合并两个区间中的数

2. 确定出区间中的中位数

左偏树就是不错的选择

复杂度$O(n\log n)$

#include <cstdio>
#include <cmath>
#include <iostream>
#define sid 1000500
#define ll long long
#define ri register int
#define ls(o) t[o].ls
#define rs(o) t[o].rs
using namespace std; char RR[];
#define isdigit(u) (u >= '0' && u <= '9')
extern inline char gc() {
static char *S = RR + , *T = RR + ;
if(S == T) S = RR, fread(RR, , , stdin);
return *S ++;
}
inline int read() {
int o = , w = ; char c = gc();
while(!isdigit(c)) {if(c == '-') w = -; c = gc();}
while(isdigit(c)) o = o * + c - '', c = gc();
return o * w;
} int n, cnt;
int rt[sid], ld[sid], rd[sid], a[sid];
struct reHeap {
int ls, rs, sz, npl, key;
} t[sid]; inline void update(int o) {
t[o].sz = t[ls(o)].sz + t[rs(o)].sz + ;
t[o].npl = t[rs(o)].npl + ;
} int merge(int x, int y) {
if(!x || !y) return x + y;
if(t[x].key < t[y].key) swap(x, y);
rs(x) = merge(rs(x), y);
if(t[rs(x)].npl > t[ls(x)].npl) swap(ls(x), rs(x));
update(x); return x;
} int main() {
n = read();
for(ri i = ; i <= n; i ++) {
ld[++ cnt] = rd[cnt] = rt[cnt] = i;
a[i] = t[i].key = read() - i; t[i].sz = ;
while(cnt > && t[rt[cnt]].key < t[rt[cnt - ]].key) {
cnt --; rd[cnt] = rd[cnt + ];
rt[cnt] = merge(rt[cnt], rt[cnt + ]);
while(t[rt[cnt]].sz * > rd[cnt] - ld[cnt] + )
rt[cnt] = merge(ls(rt[cnt]), rs(rt[cnt]));
}
}
ll ans = ;
for(ri i = ; i <= cnt; i ++)
for(ri j = ld[i]; j <= rd[i]; j ++)
ans += abs(t[rt[i]].key - a[j]);
printf("%lld\n", ans);
for(ri i = ; i <= cnt; i ++)
for(ri j = ld[i]; j <= rd[i]; j ++)
printf("%d ", t[rt[i]].key + j);
return ;
}

[BOI2004]Sequence的更多相关文章

  1. 洛谷P4331 [BOI2004] Sequence 数字序列 [左偏树]

    题目传送门 数字序列 题目描述 给定一个整数序列 a1​,a2​,⋅⋅⋅,an​ ,求出一个递增序列 b1​<b2​<⋅⋅⋅<bn​ ,使得序列 ai​ 和 bi​ 的各项之差的绝对 ...

  2. [BOI2004]Sequence 数字序列(左偏树)

    PS:参考了黄源河的论文<左偏树的特点及其应用> 题目描述:给定一个整数序列\(a_1, a_2, - , a_n\),求一个递增序列\(b_1 < b_2 < - < ...

  3. [BOI2004]Sequence 数字序列

    Description: Hint: \(n<=10^5\) Solution: 首先考虑b不严格递增时的做法 发现当\(a[i]\)递增时\(b[i]\)直接取\(a[i]\)即可,否则此时需 ...

  4. P4331 [BOI2004]Sequence 数字序列 (左偏树)

    [题目链接] https://www.luogu.org/problemnew/show/P4331 题目描述 给定一个整数序列\(a_1, a_2, ··· , a_n,\)求出一个递增序列\(b_ ...

  5. 洛谷P4331 [BOI2004]Sequence 数字序列(左偏树)

    传送门 感觉……不是很看得懂题解在说什么? 我们先把原数列$a_i-=i$,那么本来要求递增序列,现在只需要求一个非严格递增的就行了(可以看做最后每个$b_i+=i$,那么非严格递增会变为递增) 如果 ...

  6. luoguP4331 [BOI2004]Sequence 数字序列

    题意 大力猜结论. 首先将所有\(a_i\)变为\(a_i-i\),之后求不严格递增的\(b_i\),显然答案不变,最后\(b_i\)加上\(i\)即可. 考虑两种特殊情况: 1.\(a[]\)是递增 ...

  7. Luogu P4331 [BOI2004]Sequence 数字序列 (左偏树论文题)

    清晰明了%%% Fairycastle的博客 个人习惯把size什么的存在左偏树结点内,这样在外面好写,在里面就是模板(只用修改update). 可以对比一下代码(好像也差不多-) MY CODE # ...

  8. 洛谷P4331[BOI2004] sequence

    博客复活? 这个题很模板啊.随便上个左偏树.之前第一遍写对了.然后今天翻出来又写了一遍发现了一个奇奇怪怪的问题. 对比如下 上面的是AC 下面的WA 真的是一个很蠢的问题...你TM堆顶都弹出来了,堆 ...

  9. 洛谷$P4331\ [BOI2004]\ Sequence$ 数字序列 左偏树

    正解:左偏树 解题报告: 传送门$QwQ$ 开始看到的时候$jio$得长得很像之前做的一个$dp$,,, 但是$dp$那题是说不严格这里是严格? 不难想到我们可以让$a_{i},b_{i}$同时减去$ ...

随机推荐

  1. [csp-201809-3]元素选择器-编译原理

    声明:同样是参考照抄hyh学长的代码!(有问题我马上删这篇emm 题目链接:http://118.190.20.162/view.page?gpid=T77 题面: 这棵树的样子(同样是来自学长的图) ...

  2. 用java代码在创建hbase表时指定region的范围

    package com.liveyc.common.utils; import java.util.List; import org.apache.hadoop.hbase.util.Bytes; i ...

  3. Tinyos Makerules解读

    Makerules 文件解读 位于/opt/tinyos-2.1.2/support/make #-*-Makefile-*- vim:syntax=make #$Id: Makerules,v 1. ...

  4. 使用showplan.sql分析sql Performance

    在HelloDBA网站找到一个分析sql性能的工具-showplan,记录一下 showplan.sql下载路径:http://www.HelloDBA.com/Download/showplan.z ...

  5. 如何删除git远程分支(转)

    1,在开发过程中,大家在远程创建了许多分支,有些是无用的,该如何删除呢,可以参考下面的方法. 如果不再需要某个远程分支了,比如搞定了某个特性并把它合并进了远程的 master 分支(或任何其他存放 稳 ...

  6. Integer类实现方式和注意事项

    java.lang.Integer类的源代码: //定义一个长度为256的Integer数组 static final Integer[] cache = new Integer[-(-128) + ...

  7. java基础12 抽象类(及关键字:abstract)

    抽象类:abstract 1.应用的场景 我们描述一类事物时,存在着某种行为,但这种行为目前不具体,那么我们就可以抽取这种行为的声明,但是不去实现这种行为,我们就需要使用抽象类. 2.抽象的好处 强制 ...

  8. Linux环境Nginx安装、调试以及PHP安装

    linux版本:64位CentOS 6.4 Nginx版本:nginx1.8.0 php版本:php5.5 1.编译安装Nginx 官网:http://wiki.nginx.org/Install 下 ...

  9. html 简单学习

    通过记事本,依照以下四步来创建您的第一张网页. 步骤一:启动记事本 如何启动记事本: 开始    所有程序        附件            记事本 步骤二:用记事本来编辑 HTML 在记事本 ...

  10. initialization 与 finalization 执行顺序 研究

    看GIF: 第二个GIF: DEMO下载:http://files.cnblogs.com/files/del88/InitOrderDemo.zip