【题目大意】

给定一个序列t1,t2,...,tn ,求一个递增序列z1<z2<...<zn , 使得R=|t1−z1|+|t2−z2|+...+|tn−zn| 的值最小。本题中,我们只需要求出这个最小的R值。

【思路】

-这个比加延迟标记的左偏树调试得还久……WA到死……

如果ti是递增的,我们只需要取zi=ti;

如果ti是递减的,我们只需要取ti的中位数。

所以我们将ti分割成若干个区间,维护每个区间的中位数。对于[L,R]的区间,我们存放[L,(L+R)/2]在堆中。具体如下操作:

(1)加入ti,将它作为一个单独的区间。

(2)比较前一个区间的中位数(即当前栈顶的最大值)和当前区间的中位数,如果前者小于后者,就将后者压入栈中。否则将前者弹出,和后者合并。注意的是如果两个区间的大小均为奇数(注意这里说的是区间大小,即L-R+1,而不是维护中位数的堆的大小),比如3和5合并,我们只需要存4个数字,而直接合并堆中存了5个,所以弹出堆顶。

(3)把合并后的堆作为当前区间,继续操作。

某种意义上的贪心思想。

我用的是左偏树,在左偏树里同时记录了L、R、size。

不过这样操作只会得到不下降,而不是递增。据说一开始输入t[i]时,t[i]-=i即可,没有会到意思orz

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stack>
#include<cmath>
using namespace std;
const int MAXN=+;
typedef long long ll;
struct node
{
int key,dis,size;
int lson,rson,father;
int L,R; }ltree[MAXN];
int n,z[MAXN];
stack<int> S; void pushup(int x)
{
int l=ltree[x].lson,r=ltree[x].rson;
ltree[x].size=+ltree[l].size+ltree[r].size;
} void build(int rt,int x)
{
ltree[rt].key=x;
ltree[rt].dis=(rt==)?-:;
ltree[rt].size=(rt==)?:;
//不要忘了当Rt=0的时候size为0
ltree[rt].lson=ltree[rt].rson=;
ltree[rt].father=ltree[rt].L=ltree[rt].R=rt;
} int merge(int x,int y)
{
if (x== || y==) return (x+y);
if (ltree[x].key<ltree[y].key) swap(x,y);
ltree[x].L=min(ltree[x].L,ltree[y].L);
ltree[x].R=max(ltree[x].R,ltree[y].R);
ltree[x].rson=merge(ltree[x].rson,y);
int &l=ltree[x].lson,&r=ltree[x].rson;
if (ltree[l].dis<ltree[r].dis) swap(l,r);
if (r==) ltree[x].dis=;
else ltree[x].dis=ltree[r].dis+;
pushup(x);
return x;
} int del(int rt)
{
int l=ltree[rt].lson,r=ltree[rt].rson;
ltree[rt].dis=;
ltree[rt].size=;
ltree[rt].lson=ltree[rt].rson=;
int ret=merge(l,r);
ltree[ret].L=ltree[rt].L;
ltree[ret].R=ltree[rt].R;
return ret;
} void init()
{
scanf("%d",&n);
for (int i=;i<=n;i++) scanf("%d",&z[i]),z[i]-=i;
for (int i=;i<=n;i++) build(i,z[i]);
build(,);
} void solve()
{
int before=z[];
S.push();
for (int i=;i<=n;i++)
{
int now=i;
while (!S.empty())
{
int tail=S.top();
if (ltree[now].key<ltree[tail].key)
{
S.pop();
int tmp=merge(tail,now);
now=tmp;
while (ltree[now].size*>(ltree[now].R-ltree[now].L+)) now=del(now);
//不要忘记了这里是ltree[now].R-ltree[now].L+2,一开始写成了+1
if (S.empty())
{
S.push(now);
break;
}
}
else
{
S.push(now);
break;
}
}
}
ll ans=;
while (!S.empty())
{
int now=S.top();S.pop();
for (int i=ltree[now].L;i<=ltree[now].R;i++) ans+=abs(z[i]-ltree[now].key);
}
printf("%lld",ans);
} int main()
{
init();
solve();
return ;
}

【左偏树+贪心】BZOJ1367-[Baltic2004]sequence的更多相关文章

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

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

  2. BZOJ1367 [Baltic2004]sequence 堆 左偏树

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

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

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

  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. 【CF671D】Roads in Yusland(贪心,左偏树)

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

  6. BZOJ1367 BOI2004Sequence(左偏树)

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

  7. 洛谷P4331 [BOI2004] Sequence 数字序列 [左偏树]

    题目传送门 数字序列 题目描述 给定一个整数序列 a1​,a2​,⋅⋅⋅,an​ ,求出一个递增序列 b1​<b2​<⋅⋅⋅<bn​ ,使得序列 ai​ 和 bi​ 的各项之差的绝对 ...

  8. [BOI2004]Sequence 数字序列(左偏树)

    PS:参考了黄源河的论文<左偏树的特点及其应用> 题目描述:给定一个整数序列\(a_1, a_2, - , a_n\),求一个递增序列\(b_1 < b_2 < - < ...

  9. Luogu P4331 [BOI2004]Sequence 数字序列 (左偏树论文题)

    清晰明了%%% Fairycastle的博客 个人习惯把size什么的存在左偏树结点内,这样在外面好写,在里面就是模板(只用修改update). 可以对比一下代码(好像也差不多-) MY CODE # ...

随机推荐

  1. thinkphp表单验证

    之前的表单验证都是用js写的,这里也可以使用tp框架的验证.但是两者比较而言还是js验证比较好,因为tp框架验证会运行后台代码,这样运行速度和效率就会下降. 自动验证是ThinkPHP模型层提供的一种 ...

  2. marquee滚动效果

    转载两篇文章: http://blog.sina.com.cn/s/blog_49ce67fc0100atb4.html https://baike.1688.com/doc/view-d359560 ...

  3. javascript复习笔记

    /* Javascript:用来在页面中编写特效,和HTML.CSS一样都是有浏览器解析 Javascript语言: 一.JS如何运行(javascript,jscript,vbscript,appl ...

  4. FPGA编码规则检查表

    FPGA编码规则检查表 -----------------------摘自<FPGA软件测试与评价技术> 中国电子信息产业发展研究院 | 编著 1.一个单独的文件应该只包含一个单独的mod ...

  5. C++ 内联函数inline

    http://blog.csdn.net/u011327981/article/details/50601800 1.  内联函数 在C++中我们通常定义以下函数来求两个整数的最大值: 复制代码 代码 ...

  6. javascript你不知道的This

    <你不知道的javascript>这本书读了有好几遍了,似乎每一次读都有新发现,有些内容并不是一下子可以弄懂的,每次读似乎都能明白一些概念.再重读一下this关键字.这个概念非常灵活,也非 ...

  7. Android检测富文本中的<img标签并实现点击效果

    本文旨在:通过点击一张图片Toast输出位置与url链接. 闲话少说,实现原理大概是酱紫的::通过正则表达式检测富文本内的图片集合并获取url,在src=“xxx” 后面添加 onclick方法,至于 ...

  8. LSTM及其变种及其克服梯度消失

    本宝宝又转了一篇博文,但是真的很好懂啊: 写在前面:知乎上关于lstm能够解决梯度消失的问题的原因: 上面说到,LSTM 是为了解决 RNN 的 Gradient Vanish 的问题所提出的.关于 ...

  9. unittest单元测试

    unittest单元测试框架不仅可以适用于单元测试,还可以适用WEB自动化测试用例的开发与执行,该测试框架可组织执行测试用例,并且提供了丰富的断言方法,判断测试用例是否通过,最终生成测试结果.今天笔者 ...

  10. 经常报错:Communications link failure

    连接池配置中配上:<property name="validationQuery" value="SELECT 1 FROM DUAL" />