题面:BZOJ传送门

题目大意:给你一个序列$a$,让你构造一个递增序列$b$,使得$\sum |a_{i}-b_{i}|$最小,$a_{i},b_{i}$均为整数

神仙题..

我们先考虑b不递减的情况

假设现在有一段单调的序列$A$

如果$A$是递增的,显然$b[i]=a[i]$是最优解

如果$A$是递减的,$b$的每一项=序列$A$的中位数时是最优解

简单证明一下递减的情况:

1.序列$A$元素数量是奇数时,我们以中位数为对称轴,那么对称的两个数带来的贡献就是它们的差值,而中位数本身不会产生贡献,如果选取的不是中位数,必然会导致中位数产生贡献,而且对称的两个数还可能产生差值以外的贡献

2.序列$A$元素数量是偶数时,选取的数在中间的两个数之间即可,贡献都是一样的

我们如何利用这一性质呢?

我们把序列拆分成很多递减的段,递增子段的每一个数都是单独的一段

我们的目的是保证$b$不递减,即把每一段取的数画成一个函数来看是不递减的

每次我们在序列末尾加入一个数$a_{i}$,都看看这一段的中位数是否$\geq $前面一段的中位数,不满足就和前一段合并,然后依次重复此过程

为什么答案合并后不会变差?太弱了并不会证..感性理解一下吧。因为这两段原来取的就是最优解,但并不满足要求,我们也只能把两段合并,再用相同的方法求最优解了..

具体实现可以用左偏树维护大根堆,记录每一段较大的$\left \lceil \frac{n}{2} \right \rceil$个数,当两个奇数段合并时删除一次堆顶即可,记录每一段的信息可以用结构体

 #include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N1 1000010
#define ll long long
using namespace std;
const ll inf=0x3f3f3f3f3f3f3f3fll; template <typename _T> void read(_T &ret)
{
ret=; _T fh=; char c=getchar();
while(c<''||c>''){ if(c=='-') fh=-; c=getchar(); }
while(c>=''&&c<=''){ ret=ret*+c-''; c=getchar(); }
ret=ret*fh;
} struct Heap{
int fa[N1],ch[N1][],h[N1]; ll val[N1];
int merge(int x,int y)
{
if(!x||!y) return x+y;
if(val[x]<val[y]) swap(x,y);
//pushdown(x);
ch[x][]=merge(ch[x][],y); fa[ch[x][]]=x;
if(h[ch[x][]]<h[ch[x][]]) swap(ch[x][],ch[x][]);
h[x]=h[ch[x][]]+;
return x;
}
int del(int x)
{
fa[ch[x][]]=fa[ch[x][]]=;
int y=merge(ch[x][],ch[x][]);
ch[x][]=ch[x][]=;
return y;
}
}h; ll a[N1];
struct node{int l,r,x;};
node stk[N1]; int n,tp; int main()
{
scanf("%d",&n);
int i,j,x,y,len; node K; ll ans=,tmp;
for(i=;i<=n;i++) read(a[i]);
for(i=;i<=n;i++)
{
h.val[i]=a[i]-i; x=i; len=;
while(tp)
{
K=stk[tp];
if(h.val[x]>=h.val[K.x]) break;
x=h.merge(x,K.x); tp--;
if( (len&) && ((K.r-K.l+)&) ) x=h.del(x);
len+=K.r-K.l+;
}
stk[++tp]=(node){i-len+,i,x};
}
for(i=;i<=tp;i++)
for(j=stk[i].l;j<=stk[i].r;j++)
{
tmp=a[j]-(h.val[stk[i].x]+j);
ans+=((tmp>)?tmp:-tmp);
}
printf("%lld\n",ans);
return ;
}

BZOJ 1367 [Baltic2004]sequence (可并堆)的更多相关文章

  1. BZOJ 1367: [Baltic2004]sequence [可并堆 中位数]

    1367: [Baltic2004]sequence Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 1111  Solved: 439[Submit][ ...

  2. BZOJ 1367 [Baltic2004]sequence 解题报告

    BZOJ 1367 [Baltic2004]sequence Description 给定一个序列\(t_1,t_2,\dots,t_N\),求一个递增序列\(z_1<z_2<\dots& ...

  3. bzoj 1367: [Baltic2004]sequence

    1367: [Baltic2004]sequence Time Limit: 20 Sec  Memory Limit: 64 MB Description Input Output 一个整数R Sa ...

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

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

  5. BZOJ 1367([Baltic2004]sequence-左偏树+中位数贪心)

    1367: [Baltic2004]sequence Time Limit: 20 Sec   Memory Limit: 64 MB Submit: 521   Solved: 159 [ Subm ...

  6. 1367: [Baltic2004]sequence

    1367: [Baltic2004]sequence Time Limit: 20 Sec  Memory Limit: 64 MB Submit: 1090  Solved: 432 [Submit ...

  7. 【BZOJ】1367: [Baltic2004]sequence

    题意 给\(n(n \le 10^6)\)个数的序列\(a\),求一个递增序列\(b\)使得\(\sum_{i=1}^{n} |a_i-b_i|\)最小. 分析 神题啊不会. 具体证明看黄源河论文&l ...

  8. 【bzoj1367】[Baltic2004]sequence 可并堆

    题目描述 输入 输出 一个整数R 样例输入 7 9 4 8 20 14 15 18 样例输出 13 题解 可并堆,黄源河<左偏树的特点及其应用>Page 13例题原题 #include & ...

  9. 【bzoj1367】[Baltic2004]sequence

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

随机推荐

  1. 手把手实现Java权限(1)-Shiro介绍

    功能介绍 Authentication :身份认证/登录.验证用户是不是拥有对应的身份:  Authorization :授权,即权限验证.验证某个已认证的用户是否拥有某个权限:即推断用  户能否做事 ...

  2. HDU 5191

    好端端的被HACK掉了...应该是在两端都要补W个0才对,之前只想到要在后面补足0,没想到前面也应该补足,因为前面即便存在0也可能使得移动的积木数最少.. T_T #include <iostr ...

  3. Create and Call HttpHandler in SharePoint

    Create and Call HttpHandler in SharePoint Requirement: 1. Create a httphandler, and reture json data ...

  4. ArcGIS Python实现Modis NDVI批量化月最大合成

    最大合成法(MVC)能够在Envi中的Band Math中进行,式子是B1>B2,可是无法批量化.本文实如今ArcGIS中利用Python代码批量进行,例如以下: 用到的Modis NDVI数据 ...

  5. 国产芯片任重道远 国科微SSD主控芯片的“追赶之路”(不能只提供一颗芯片,而是要将芯片、国密算法、固件Firmware、BIOS和操作系统紧密联系在一起,变成完整解决方案交给行业用户,才能真正体现自身的价值)

    集微网消息,“中国芯”战略之路道阻且长,踏入这个赛道的攻坚者们需要十年如一日的技术突破,需要集合产业势能,共同协作,方能建立中国核心技术真正的竞争力. 国产化之路任重道远,SSD芯片初见成效 信息时代 ...

  6. 36岁IT老人再次随笔——程序员的门槛其实并不高,但却是一个易学难精的行当——IT的快车很快,我常看到不少人摔落下去,但又有不少身手敏捷的人跳了上来 good

    36岁的我,还在IT里面留恋着技术.我不是什么技术牛人,只是不愿离开.搞硬件的朋友对我说:“我以为你是搞硬件的,没想到你软件方面这么厉害?”,搞软件的朋友对我说:“我以为你只是搞软件的,没想到你硬件方 ...

  7. SVGImageView

    In essence, I'm trying to layer multiple ImageViews (one of which is a floor plan, the other a recta ...

  8. Python使用装饰器自动调用父类__init__

    众所周知,Python中class的构造函数实际是__new__(),但是如果我们执行p1=Point()的时候,不仅会调用Point的__new__方法,而且会调用Point的__init__方法. ...

  9. consul 集群安装

    上图是官网提供的一个事例系统图,图中的Server是consul服务端高可用集群,Client是consul客户端.consul客户端不保存数据,客户端将接收到的请求转发给响应的Server端.Ser ...

  10. Fabric quickly

    环境很重要.环境很重要.环境很重要 # CentOS 7 $ setenforce 0 # 可以设置配置文件永久关闭 $ systemctl stop iptables.service $ syste ...