题目传送门

https://lydsy.com/JudgeOnline/problem.php?id=1367

题解

先考虑条件为要求不下降序列(不是递增)的情况。

那么考虑一段数值相同的子段,这一段相同的数值显然应该是原序列 \(t\) 中对应的位置上的数的中位数。

(不是中位数答案一定比中位数大)

所以问题转化为划分成很多段,每一段的权值是中位数,要求权值不下降。

对于一段,每一次往前扫,只要前面的中位数比它大,那么就合并。

可以用可并堆维护每一段,只保留中位数以下的数。合并左偏树实现即可。

不过题目的要求是上升序列,但是我们求出来的是不下降序列。所以可以把 \(t_i\) 都减去 \(i\),这样就可以把上升序列转化为不下降序列了。


时间复杂度 \(O(n\log n)\)。

#include<bits/stdc++.h>

#define fec(i, x, y) (int i = head[x], y = g[i].to; i; i = g[i].ne, y = g[i].to)
#define dbg(...) fprintf(stderr, __VA_ARGS__)
#define File(x) freopen(#x".in", "r", stdin), freopen(#x".out", "w", stdout)
#define fi first
#define se second
#define pb push_back template<typename A, typename B> inline char smax(A &a, const B &b) {return a < b ? a = b, 1 : 0;}
template<typename A, typename B> inline char smin(A &a, const B &b) {return b < a ? a = b, 1 : 0;} typedef long long ll; typedef unsigned long long ull; typedef std::pair<int, int> pii; template<typename I> inline void read(I &x) {
int f = 0, c;
while (!isdigit(c = getchar())) c == '-' ? f = 1 : 0;
x = c & 15;
while (isdigit(c = getchar())) x = (x << 1) + (x << 3) + (c & 15);
f ? x = -x : 0;
} const int N = 1e6 + 7; #define lc c[0]
#define rc c[1] int n, cc;
int a[N], rt[N], s[N], siz[N], siz2[N], st[N]; struct Node { int c[2], v, dis; } t[N];
inline int merge(int o, int p) {
if (!o || !p) return o ^ p;
if (t[o].v < t[p].v) std::swap(o, p);
t[o].rc = merge(t[o].rc, p);
if (t[t[o].lc].dis < t[t[o].rc].dis) std::swap(t[o].lc, t[o].rc);
t[o].dis = t[t[o].rc].dis + 1;
return o;
}
inline void pop(int &o) { o = merge(t[o].lc, t[o].rc); } inline void work() {
for (int i = 1; i <= n; ++i) {
// dbg("i = %d\n", i);
rt[++cc] = i, t[i].v = a[i], siz[cc] = siz2[cc] = 1, st[cc] = i;
while (cc > 1 && t[rt[cc]].v <= t[rt[cc - 1]].v) {
--cc;
rt[cc] = merge(rt[cc], rt[cc + 1]);
siz[cc] += siz[cc + 1], siz2[cc] += siz2[cc + 1];
while (siz2[cc] > (siz[cc] + 1) / 2) pop(rt[cc]), --siz2[cc];
}
}
ll ans = 0;
st[cc + 1] = n + 1;
for (int i = 1; i <= cc; ++i)
for (int j = st[i]; j < st[i + 1]; ++j) ans += abs(t[rt[i]].v - a[j]);
printf("%lld\n", ans);
} inline void init() {
read(n);
for (int i = 1; i <= n; ++i) read(a[i]), a[i] -= i;
} int main() {
#ifdef hzhkk
freopen("hkk.in", "r", stdin);
#endif
init();
work();
fclose(stdin), fclose(stdout);
return 0;
}

bzoj1367 [Baltic2004]sequence 左偏树+贪心的更多相关文章

  1. BZOJ1367: [Baltic2004]sequence(左偏树)

    Description Input Output 一个整数R Sample Input 7 9 4 8 20 14 15 18 Sample Output 13 解题思路: 有趣的数学题. 首先确定序 ...

  2. 【BZOJ1367】[Baltic2004]sequence 左偏树

    [BZOJ1367][Baltic2004]sequence Description Input Output 一个整数R Sample Input 7 9 4 8 20 14 15 18 Sampl ...

  3. 【左偏树+贪心】BZOJ1367-[Baltic2004]sequence

    [题目大意] 给定一个序列t1,t2,...,tn ,求一个递增序列z1<z2<...<zn , 使得R=|t1−z1|+|t2−z2|+...+|tn−zn| 的值最小.本题中,我 ...

  4. BZOJ1367 BOI2004Sequence(左偏树)

    首先考虑把bi和ai同时减i,问题变为非严格递增.显然如果a是一个递减序列,b序列所有数都取其中位数最优.于是划分原序列使得每一部分递减,然后考虑合并相邻两段.如果前一段的中位数<=后一段的中位 ...

  5. bzoj 1367 [ Baltic 2004 ] sequence —— 左偏树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1367 好题啊!论文上的题: 论文上只给出了不下降序列的求法: 先考虑特殊情况,如果原序列上升 ...

  6. BZOJ1367 [Baltic2004]sequence 堆 左偏树

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1367 题意概括 Description Input Output 一个整数R 题解 http:// ...

  7. BZOJ1367 [Baltic2004]sequence 【左偏树】

    题目链接 BZOJ1367 题解 又是一道神题,, 我们考虑一些简单的情况: 我们先假设\(b_i\)单调不降,而不是递增 对于递增序列\(\{a_i\}\),显然答案\(\{b_i\}\)满足\(b ...

  8. 【BZOJ 1367】 1367: [Baltic2004]sequence (可并堆-左偏树)

    1367: [Baltic2004]sequence Description Input Output 一个整数R Sample Input 7 9 4 8 20 14 15 18 Sample Ou ...

  9. 【CF671D】Roads in Yusland(贪心,左偏树)

    [CF671D]Roads in Yusland(贪心,左偏树) 题面 洛谷 CF 题解 无解的情况随便怎么搞搞提前处理掉. 通过严密(大雾)地推导后,发现问题可以转化成这个问题: 给定一棵树,每条边 ...

随机推荐

  1. 四、IDEA创建SpringBoot项目

    1.从官网下载之后直接导入IDEA: 下载完成解压之后如下图: IDEA导入该项目: 之后一路next即可 导入成功之后你可能会发现左下角一直有个进度条在进行,傻傻的同学可能以为是在下载jar包,下个 ...

  2. JavaScript中this的一些练习

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. 送书福利| Python 完全自学手册

    前言 这里不讨论「能不能学,要不要学,应不应该学 Python」的问题,这里只会告诉你怎么学. 首先需要强调的是,如果 Python 都学不会,那么我建议你考虑别的行业,因为 Python 之简单,令 ...

  4. Python 笔试集(1):关于 Python 链式赋值的坑

    前言 Python 的链式赋值是一种简易型批量赋值语句,一行代码即可为多个变量同时进行赋值. 例如: x = y = z = 1 链式赋值是一种非常优雅的赋值方式,简单.高效且实用.但同时它也是一个危 ...

  5. 测开之路一百二十八:flask之重定向和404

    a.b两个视图,分别返回a的页面和b的页面 重定向:redirect 重定向到路由:请求/a/时,重定向到/b/ 重定向到视图函数:url_for(“函数名“),访问/a/时,重定向到函数b() 主动 ...

  6. SPA(single page application)

    一.SPA的概述 SPA(single page application)单页面应用程序,在一个完成的应用或者站点中,只有一个完整的html页面,这个页面有一个容器,可以把需要加载的代码片段插入到该容 ...

  7. 配置idea中类头注释中的 ${user} 自动获取电脑的名字,怎么去修改名字

    在idea安装路径下找到 idea\IntelliJ IDEA 2018.3.2\bin下面有一个文件叫:idea64.exe.vmoptions 编辑此文件就能修改主时钟自动获取的名称: 例如:添加 ...

  8. codeforces 1186C Vus the Cossack and Strings

    题目链接:https://codeforc.es/contest/1186/problem/C 题目大意:xxxxx(自认为讲不清.for instance) 例如:a="01100010& ...

  9. Lesson 1 A puma at large

    spot (v) 看出,发现 oblige (v) 使...感到必须:obliged (adj)必须的, feel obliged to do sth. 感到不得不做某事 ==have to.eg:E ...

  10. xmake入门,构建项目原来可以如此简单

    前言 在开发xmake之前,我一直在使用gnumake/makefile来维护个人C/C++项目,一开始还好,然而等项目越来越庞大后,维护起来就非常吃力了,后续也用过一阵子automake系列工具,并 ...