码迷,mamicode.com
首页 > 其他好文 > 详细

[Baltic2004]数字序列

时间:2018-02-22 19:22:38      阅读:177      评论:0      收藏:0      [点我收藏+]

标签:一段   保存   swap   复杂度   log   algorithm   logs   pac   space   

原题请见《左偏树的特点及其应用》BY 广东省中山市第一中学 黄源河

题意

给出序列\(a[1...n]\),要求构造序列\(b[1...n]\)使得\(\sum_{i=1}^{n}|a_i-b_i|\)最小。

sol

首先很自然地能够想到,构造出来的序列\(b[1...n]\)一定可以划分成\(m\)\((1\le{m}\le{n})\),每段内数字全部相同。
我们把每一段的数字提取出来分别为\(c[1...m]\)
如果对每一段的\(c[i]\)都取最优的话,那么一定是去这一段中\(a[i]\)的中位数。
但是取中位数可能会导致序列\(c\)不满足非降,这个时候就需要把相邻的两个不合法的段合并成一段。
所以就需要维护中位数。
左偏树。对于一个长度为\(x\)的段,左偏树中保存这一段中前\(\lfloor\frac{x+1}{2}\rfloor\)小的数字,易知这些数里面最大的那个就是中位数,合并的时候直接合并两棵左偏树。
因为\(\lfloor\frac{x+1}{2}\rfloor+\lfloor\frac{y+1}{2}\rfloor=\lfloor\frac{x+y+1}{2}\rfloor-1\)当且仅当\(x,y\)均为奇数,所以这种情况要弹掉堆顶元素。
复杂度\(O(n\log{n})\)

code

#include<cstdio>
#include<algorithm>
using namespace std;
#define ll long long
inline int gi()
{
    int x=0,w=1;char ch=getchar();
    while ((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    if (ch=='-') w=0,ch=getchar();
    while (ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    return w?x:-x;
}
const int N = 1e6+5;
int n,key[N],ls[N],rs[N],dis[N],S[N],ed[N],top;
ll ans;
int merge(int A,int B)
{
    if (!A||!B) return A|B;
    if (key[A]<key[B]) swap(A,B);
    rs[A]=merge(rs[A],B);
    if (dis[ls[A]]<dis[rs[A]]) swap(ls[A],rs[A]);
    dis[A]=dis[rs[A]]+1;
    return A;
}
int main()
{
    n=gi();
    for (int i=1;i<=n;++i) key[i]=gi();
    for (int i=1;i<=n;++i)
    {
        ++top;S[top]=i;ed[top]=i;
        while (top>1&&key[S[top]]<key[S[top-1]])
        {
            --top;
            S[top]=merge(S[top],S[top+1]);
            if (((ed[top+1]-ed[top])&1)&&((ed[top]-ed[top-1])&1))
                S[top]=merge(ls[S[top]],rs[S[top]]);
            ed[top]=ed[top+1];
        }
    }
    for (int i=1;i<=top;++i)
        for (int j=ed[i-1]+1;j<=ed[i];++j)
            ans+=abs(key[j]-key[S[i]]);
    printf("%lld\n",ans);
    return 0;
}

[Baltic2004]数字序列

标签:一段   保存   swap   复杂度   log   algorithm   logs   pac   space   

原文地址:https://www.cnblogs.com/zhoushuyu/p/8459263.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!