n<=1e6个数,把他们修改成递增序列需把每个数增加或减少的总量最小是多少?

方法一:可以证明最后修改的每个数一定是原序列中的数!于是$n^2$DP(逃)

方法二:把$A_i$改成$A_i-i$,变论文题:论文

大概证明是这样的:考虑合并两个区间的答案,假如一个区间答案是{u,u,u,……,u},另一个是{v,v,v,……,v},那合并之后,如果u<=v最优就{u,u,……,u,v,……,v};如果u>v,假设最优是

{b1,b2,……,bn,bn+1,……,bm},那么一定有bn<=u,否则把前半部分改成{u,u,……,u}不会更差。同理bn+1>=v。

这里有个不懂的地方:

因此可以把他改成{bn,bn,……,bn,bn+1,……,bn+1},不会更差。可以用几何意义感性理解一下:左边离u越近越优,右边离v越近越优。

然后由于bn<=u,bn+1>=v,本着“bn能大就大,bn+1能小就小”的原则让bn=bn+1。于是合并后的最优解为{w,w,w,……,w},最优的w是谁呢?肯定是整个区间的中位数啦。

然后就可以可并堆做一波合并了,因为这里合并后中位数只会变小,可以维护一个区间的一半小的数或一半大的数,合并两个区间时,如果两个区间大小都是奇数,则堆里会多出一个数,删之。

可并堆常需合并特定点所在的堆,因此常与并查集连用。千万别并查集懵逼了!!因为并查集操作失误调了一晚上。。

 #include<string.h>
#include<stdlib.h>
#include<stdio.h>
#include<math.h>
//#include<assert.h>
#include<algorithm>
//#include<iostream>
using namespace std; int n;
#define maxn 1000011
int root[maxn];
int find(int x) {return x==root[x]?x:(root[x]=find(root[x]));}
struct leftist
{
struct Node
{
int v,ls,rs,dis,size;
}a[maxn];
int size;
leftist() {a[].dis=-;}
int merge(int x,int y)
{
if (!x || !y) return x^y;
if (a[x].v<a[y].v) {int t=x; x=y; y=t;}
a[x].rs=merge(a[x].rs,y);
if (a[a[x].ls].dis<a[a[x].rs].dis) {int t=a[x].ls; a[x].ls=a[x].rs; a[x].rs=t;}
a[x].dis=a[a[x].rs].dis+;
a[x].size=a[a[x].ls].size+a[a[x].rs].size+;
return x;
}
void push(int x,int &root,int val)
{
a[x].v=val; a[x].ls=a[x].rs=a[x].dis=; a[x].size=;
root=merge(root,x);
}
int top(int root) {return a[root].v;}
void pop(int &root) {root=merge(a[root].ls,a[root].rs);}
}q; int a[maxn],sta[maxn],die[maxn],top;
int main()
{
scanf("%d",&n);
for (int i=;i<=n;i++) scanf("%d",&a[i]),a[i]-=i;
for (int i=;i<=n;i++)
{
q.push(i,root[i],a[i]); int x,y;
while (top && q.top(x=find(root[sta[top]]))>q.top(y=find(root[i])))
{
bool flag=;
if (((sta[top]-sta[top-])&) && ((i-sta[top])&)) flag=;
root[x]=root[y]=q.merge(x,y); x=root[x];
if (flag) die[x]=,q.pop(root[x]),root[root[x]]=root[x];
top--;
}
sta[++top]=i;
}
#define LL long long
LL ans=;
for (int i=;i<=n;i++) ans+=fabs(a[i]-q.top(find(root[i])));
printf("%lld\n",ans);
return ;
}

可并堆试水--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(左偏树)

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

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

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

  6. BZOJ1367——[Baltic2004]sequence

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

  7. 【bzoj1367】[Baltic2004]sequence

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

  8. POJ 2502 - Subway Dijkstra堆优化试水

    做这道题的动机就是想练习一下堆的应用,顺便补一下好久没看的图论算法. Dijkstra算法概述 //从0出发的单源最短路 dis[][] = {INF} ReadMap(dis); for i = 0 ...

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

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

随机推荐

  1. shell编写的多服务器自动互信脚本(安装ceph)

    相信大家都使用过分布式存储,而在分布式存储中较为出色的非ceph莫属了,但是这里就不深入聊ceph啦,我们只是聊聊安装ceph时遇到的问题. ceph需要多台主机进行ssh互信.三台还能忍受,但是当超 ...

  2. 【C++】模板简述(六):总结

    1.模板技术是泛型编程的基础.([C++]模板简述(一):模板的引入) 2.模板被编译两次,因而给分离编译造成一些麻烦.([C++]模板简述(二):函数模板.[C++]模板简述(四):模板为什么不支持 ...

  3. 迅为iTOP-4418/6818开发板MiniLinux下的GPS使用手册

    平台:iTOP-4418/6818开发板 系统:MiniLinux 在 Mini Linux 系统环境下 iTOP-4418 和 6818 的 GPS 实验调试步骤.给用户提供了“iTOP-4418- ...

  4. col - 过滤掉输入中的反向换行符

    SYNOPSIS(总览) col [-bfx ] [ Fl l Ar num ] DESCRIPTION(描述) Col 过滤掉反向(以及半反向)换行符(LF: line feed or NL: ne ...

  5. React和webpack解决 waiting for roots to load...to reload the inspector

    使用chrome调试工具,react-devtools总是显示 "waiting for roots to load...to reload the inspector" and ...

  6. PHP 中 echo 和 print 的区别

    一般来说,PHP中动态输出HTML内容,是通过print 和 echo 语句来实现的,在实际使用中, print 和 echo 两者的功能几乎是完全一样.可以这么说,凡是有一个可以使用的地方,另一个也 ...

  7. JS日期,金钱处理

    一丶获取两个时间的天数 <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> ...

  8. count() 方法

    count() :方法用于统计字符串里某个字符出现的次数.可选参数为在字符串搜索的开始与结束位置. num1,num2 = input('请输入字符串:'),input('请输入要查询的子串:') p ...

  9. Ubuntu下systemd服务的配置

    1. 在/lib/systemd/system目录下创建服务启动脚本testservice.service 2. 文件内容如下: [Unit] Description=TestService [Ser ...

  10. 路径工具类NSPathUtilities

    路径工具类NSPathUtilities.h 路径类NSPathUtilities.h包含了 NSString的函数和分类扩展,他允许你操作路径名.应该竟可能的使用这些函数,以便使程序更独立于文件系统 ...