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. 在Paint事件中绘制控件(边框)

    单纯的自己记录,将来会继续添加,侥幸被大家发现了的话请不要太鄙视... private void panel4_Paint(object sender, PaintEventArgs e) { Con ...

  2. Sort排序浅聊

    集合是什么?笔者简易描述:数组是不可变的,所以我们使用集合来代替. using.System.Collections; 非泛型集合 using.System.Collections.Gernerc;泛 ...

  3. vue cli 3 打包过大问题

    vue cli 3 打包命令 npm run build,这种情况下的打包可以通过设置 vue.config.js里面的 productionSourceMap: false. 如果是自己设置的打包环 ...

  4. vue报错-Error: Cannot find module '@babel/core'

    vue之webpack实战的时候遇到报错,Error: Cannot find module '@babel/core' 这报错,我百度了很久,后来发现报错里面有提示,发现是我的 babel-load ...

  5. spring 整合struts

    1.例子:未被spring整合 struts.xml 的配置文件 <constant name="struts.enable.DynamicMethodInvocation" ...

  6. VM virtualBox设置无缝全屏

    设置之前:

  7. 玩转CPU运行曲线

    Leaf 是不是从来没有想过看看cpu运行曲线啊骚年?顶多也就仅仅是看看cpu利用率,吓自己一跳后感觉关闭几个不该打开的程序~ 然而问题来了,微软公司要让你绘制cpu运行曲线啊!!不仅是固定的直线,还 ...

  8. 企业面试之LeetCode刷题心得

    谈起刷LeetCode的心得,想要先扯点别的,说实话我是比较自虐的人,大学时候本专业从来不好好上,一直觊觎着别人的专业,因为自己文科生,总觉得没有项技术在身出门找工作都没有底气,然后看什么炫学什么,简 ...

  9. 【转】nABC法-产品分析思路

    Needs:需求N1,用户最基本需求是什么?N2,市场有多大?N3,行业链如何构成?N4,行业发展趋势如何?N5,扩充的需求有哪些? Approach:解决方案A1,解决方案如何构成?A2,需求优先级 ...

  10. python学习第三次

    while循环 表示当条件成立的时候就循环适用于不知道具体循环次数,但是确定在某个条件成立的情况下就循环while语法:while 条件表达式:语句块#另一种表达方式while 条件表达式:语句块1e ...