1、题目大意:给一个序列t,然后求一个序列z,使得$|z1-t1|+|z2-t2|+...+|zn-tn|$的值最小,我们只需要求出这个值就可以了,并且z序列是递增的

2、分析:这道题z序列是递增的,不好做啊,我们想让z序列变成不降的,可以将t数组进行改变,就是t[i]-=i。不降的就好做多了,我们可以让一段下降的t序列对应的z序列全是中位数。但是我们还要维护z序列是单调的,于是我们从头扫,用一个单调栈,对于每一个t,先压进栈,如果栈顶元素的中位数比栈的第二个元素要小,就把栈顶和第二个元素合并,维护中位数。最后用这个栈中的元素算出z序列,最后就是求值了

#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
#define M 1100000
#define LL long long
struct merge_heap{
    int l[M], r[M], d[M], value[M];
    void init(){
        memset(l, 0, sizeof(r));
        memset(r, 0, sizeof(r));
        memset(d, 1, sizeof(d));
    }
    int merge(int x, int y){
        if(!x) return y;
        if(!y) return x;
        if(value[x] < value[y]) swap(x, y);
        r[x] = merge(r[x], y);
        if(d[l[x]] < d[r[x]]){
            swap(l[x], r[x]);
        }
        d[x] = d[l[x]] + 1;
        return x;
    }
} wt;
int L[M], R[M], tree[M], Size[M], Top = 0, t[M], z[M];
int main(){
    wt.init();
    int n;
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++) scanf("%d", &t[i]);
    for(int i = 1; i <= n; i ++) t[i] -= i;
    for(int i = 1; i <= n; i ++){
        wt.value[i] = t[i];
        tree[++ Top] = i;
        L[Top] = R[Top] = i;
        Size[Top] = 1;
        while(Top > 1 && wt.value[tree[Top]] <= wt.value[tree[Top - 1]]){
            R[Top - 1] = R[Top];
            Size[Top - 1] += Size[Top];
            tree[Top - 1] = wt.merge(tree[Top - 1], tree[Top]);
            Top --;
            int len = R[Top] - L[Top] + 1;
            if(len % 2 == 0){
                len /= 2;
            }
            else{
                len = len / 2 + 1;
            }
            while(Size[Top] > len){
                Size[Top] --;
                tree[Top] = wt.merge(wt.l[tree[Top]], wt.r[tree[Top]]);
            }
        }
    }
    for(int i = 1; i <= Top; i ++){
        for(int j = L[i]; j <= R[i]; j ++){
            z[j] = wt.value[tree[i]];
        }
    }
    LL ans = 0;
    for(int i = 1; i <= n; i ++){
        ans += (LL)(abs(z[i] - t[i]));
    }
    printf("%lld\n", ans);
    return 0;
}

BZOJ1367——[Baltic2004]sequence的更多相关文章

  1. BZOJ1367 [Baltic2004]sequence 堆 左偏树

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

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

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

  3. BZOJ1367 [Baltic2004]sequence

    现学的左偏树...这可是道可并堆的好题目. 首先我们考虑z不减的情况: 我们发现对于一个区间[l, r],里面是递增的,则对于此区间最优解为z[i] = t[i]: 如果里面是递减的,z[l] = z ...

  4. 可并堆试水--BZOJ1367: [Baltic2004]sequence

    n<=1e6个数,把他们修改成递增序列需把每个数增加或减少的总量最小是多少? 方法一:可以证明最后修改的每个数一定是原序列中的数!于是$n^2$DP(逃) 方法二:把$A_i$改成$A_i-i$ ...

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

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

  6. bzoj1367 [Baltic2004]sequence 左偏树+贪心

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=1367 题解 先考虑条件为要求不下降序列(不是递增)的情况. 那么考虑一段数值相同的子段,这一段 ...

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

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

  8. 【bzoj1367】[Baltic2004]sequence

    2016-05-31 17:31:26 题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1367 题解:http://www.cnblogs.co ...

  9. 【BZOJ-1367】sequence 可并堆+中位数

    1367: [Baltic2004]sequence Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 932  Solved: 348[Submit][S ...

随机推荐

  1. javascript应用之如何判断一个数为素数

    判断是否为素数? 质数(prime number)又称素数,有无限个.质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数的数称为质数. 合数,数学用语,英文名为Composite numb ...

  2. Setting up Django and your web server with uWSGI and nginx

    https://uwsgi.readthedocs.io/en/latest/tutorials/Django_and_nginx.html Setting up Django and your we ...

  3. electron打包

    1.全局安装electron-packager npm install -g electron-packager 2.在项目目录下执行命令 electron-packager ./ --platfor ...

  4. $(document).ready、body.Onload()和 $(window).load的区别

    window.load(function(){...})和body.onload()都存在同样一个问题,那都是在页面所有元素(包括html标签以及引用到得所有图片,Flash等媒体)加载完毕后执行的, ...

  5. Linux的95个小技巧

    Linux的95个小技巧 by WEB全栈工程师 on 2012 年 03 月 27 日 这里总结了Linux使用中的一些小技巧 1.实现RedHat非正常关机的自动磁盘修复 先登录到服务器,然后在/ ...

  6. 自然语言12_Tokenizing Words and Sentences with NLTK

    https://www.pythonprogramming.net/tokenizing-words-sentences-nltk-tutorial/ # -*- coding: utf-8 -*- ...

  7. JavaWeb学习笔记——DOM4J

    下载的地址为:http://www.dom4j.org/dom4j-1.6.1/ import java.io.File; import java.io.FileOutputStream; impor ...

  8. HTTP2.0的二进制分帧

    1.帧的类型: 在二进制分帧的结构中,头部有8个字节(64Bit),其中有一个字节(8Bit)来标志帧的类型: HTTP2.0规定了如下帧类型: DATA: 用于传输HTTP消息体 HEADERS:用 ...

  9. Fragment碎片的创建和动态更新

    Fragment,在平板应用中较为参见,把视图分为两个甚至多个模块. 一,一个简单的fragment 1.创建两个局部文件,用于等待被调用 (1)left_fragment (2)right_frag ...

  10. phpize 扩展GD库 安装 ! 环境--centos 7 +nginx 1.7.11+php 5.6.7

    使用phpize编译GD库安装,先安装前置库libjpeg libpng zlib  freetype等 都是下面php编译的几个选项 先看php编译的选项: --with-gd=DIR       ...