zoukankan      html  css  js  c++  java
  • BZOJ_1367_[Baltic2004]sequence_结论题+可并堆

    BZOJ_1367_[Baltic2004]sequence_结论题+可并堆

    Description

    Input

    Output

    一个整数R

    Sample Input

    7
    9
    4
    8
    20
    14
    15
    18

    Sample Output

    13

    HINT

    所求的Z序列为6,7,8,13,14,15,18.
    R=13


    神题。有一个结论:最优解一定是把序列分成m块,每块取中位数,并使得取出的序列递增。

    不会证?https://wenku.baidu.com/view/20e9ff18964bcf84b9d57ba1.html

    然后发现后面的合法中位数递增,搞来一个可并大根堆来维护,当堆内元素超过序列的一半时弹出。

    然而结论要求序列不降,这里求序列递增。

    我们发现每个递增的序列的每个数$ai$ 减去$i$ 对应着唯一一个不降序列,故在一开始对序列进行处理。

    代码:

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    char nc() {
        static char buf[100000],*p1,*p2;
        return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
    }
    inline int rd() {
        register int x=0; register char s=nc();
        while(s<'0'||s>'9') s=nc();
        while(s>='0'&&s<='9') x=x*10+s-'0',s=nc();
        return x;
    }
    int fabs(int x){return x>0?x:-x;}
    #define N 1000050
    typedef long long ll;
    int n,a[N],root[N],siz[N],val[N],ls[N],rs[N],dis[N],lp[N],rp[N];
    ll ans;
    int merge(int x,int y) {
        if(!x) return y;
        if(!y) return x;
        if(val[x]<val[y]) swap(x,y);
        siz[x]+=siz[y];
        rs[x]=merge(rs[x],y);
        if(dis[rs[x]]>dis[ls[x]]) swap(ls[x],rs[x]);
        dis[x]=dis[rs[x]]+1;
        return x;
    }
    int main() {
        n=rd(); 
        int i,tot=0,m=0,j;
        for(i=1;i<=n;i++) a[i]=rd(),a[i]-=i;
        dis[0]=-1;
        for(i=1;i<=n;i++) {
            root[++m]=++tot; val[tot]=a[i]; siz[tot]=1; lp[m]=rp[m]=i;
            while(m>1&&val[root[m]]<val[root[m-1]]) {
                m--; root[m]=merge(root[m],root[m+1]); rp[m]=rp[m+1];
                while(2*siz[root[m]]>rp[m]-lp[m]+2) root[m]=merge(ls[root[m]],rs[root[m]]);
            }
        }
        for(i=1;i<=m;i++) {
            for(j=lp[i];j<=rp[i];j++) {
                ans+=fabs(val[root[i]]-a[j]);
            }
        }
        printf("%lld
    ",ans);
    }
    
  • 相关阅读:
    【转载】Android IntentService使用全面介绍及源码解析
    【转载】作为Android开发者,你真的熟悉Activity吗?
    【转载】从使用到原理学习Java线程池
    Linux 基础知识+常见命令
    Python中的字典合并
    Python的__hash__函数和__eq__函数
    C#中实现Hash应用
    深入理解python元类
    Docker搭建Gitlab服务器
    python的加密方式
  • 原文地址:https://www.cnblogs.com/suika/p/8891493.html
Copyright © 2011-2022 走看看