可并堆试水--BZOJ1367: [Baltic2004]sequence
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的更多相关文章
- BZOJ1367 [Baltic2004]sequence 堆 左偏树
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1367 题意概括 Description Input Output 一个整数R 题解 http:// ...
- BZOJ1367 [Baltic2004]sequence 【左偏树】
题目链接 BZOJ1367 题解 又是一道神题,, 我们考虑一些简单的情况: 我们先假设\(b_i\)单调不降,而不是递增 对于递增序列\(\{a_i\}\),显然答案\(\{b_i\}\)满足\(b ...
- BZOJ1367 [Baltic2004]sequence
现学的左偏树...这可是道可并堆的好题目. 首先我们考虑z不减的情况: 我们发现对于一个区间[l, r],里面是递增的,则对于此区间最优解为z[i] = t[i]: 如果里面是递减的,z[l] = z ...
- BZOJ1367: [Baltic2004]sequence(左偏树)
Description Input Output 一个整数R Sample Input 7 9 4 8 20 14 15 18 Sample Output 13 解题思路: 有趣的数学题. 首先确定序 ...
- bzoj1367 [Baltic2004]sequence 左偏树+贪心
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=1367 题解 先考虑条件为要求不下降序列(不是递增)的情况. 那么考虑一段数值相同的子段,这一段 ...
- BZOJ1367——[Baltic2004]sequence
1.题目大意:给一个序列t,然后求一个序列z,使得$|z1-t1|+|z2-t2|+...+|zn-tn|$的值最小,我们只需要求出这个值就可以了,并且z序列是递增的 2.分析:这道题z序列是递增的, ...
- 【bzoj1367】[Baltic2004]sequence
2016-05-31 17:31:26 题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1367 题解:http://www.cnblogs.co ...
- POJ 2502 - Subway Dijkstra堆优化试水
做这道题的动机就是想练习一下堆的应用,顺便补一下好久没看的图论算法. Dijkstra算法概述 //从0出发的单源最短路 dis[][] = {INF} ReadMap(dis); for i = 0 ...
- 【BZOJ 1367】 1367: [Baltic2004]sequence (可并堆-左偏树)
1367: [Baltic2004]sequence Description Input Output 一个整数R Sample Input 7 9 4 8 20 14 15 18 Sample Ou ...
随机推荐
- AngularJS ng-repeat下使用ng-model
1 2 3 blue:<input type="radio" value="1" ng-model="selectValue"/> ...
- git ---匿名分支和checkout命令
git checkout -b //创建一个匿名分支
- lua使用lfs.dll库进行文件操作
在项目开发中,为了提高开发效率往往需要开发一些辅助工具.最近在公司用lua帮拓展了一个资源扫描的工具,这个工具的功能就是从原始demo下指定目标资源文件,对该文件进行读取并筛选过滤一遍然后拷贝到最终d ...
- java实现的判断括号是否成对的代码,()[]{}都可以
本来想找找现成的,去,都写的好复杂.自己写一个吧.挺有成就感.哈哈 package com.test.jiexi; import java.util.Stack; public class Check ...
- _bbox_pred函数
fast中的_bbox_pred函数和faster中的bbox_transform_inv是一样的,是将框进行4个坐标变换得到新的框坐标.fast中是将selective search生成的框坐标进行 ...
- Java之Servlet文件下载20190228
jsp页面: <%@ page language="java" contentType="text/html; charset=utf-8" pageEn ...
- jdk11 eclipse下开启ZGC
平台支持 ZGC目前只在Linux/x64上可用,如果有足够的需求,将来可能会增加对其他平台的支持. 对的,目前只支持64位的linux系统. -_-' eclipse.ini配置: -XX:+Unl ...
- 第3节 mapreduce高级:5、6、通过inputformat实现小文件合并成为sequenceFile格式
1.1 需求 无论hdfs还是mapreduce,对于小文件都有损效率,实践中,又难免面临处理大量小文件的场景,此时,就需要有相应解决方案 1.2 分析 小文件的优化无非以下几种方式: 1. 在数据 ...
- C# WebService 的缓存机制
C# WebService 的缓存机制 [转]WebService的缓存机制 2008年02月19日 星期二 11:22 WebService的缓存分为两种,一种是简单的输出缓存,一种是强大的数据 ...
- eclipse包分层
方法很简单,如下图所示: 1.点击项目栏窗口的右上角的倒三角 2.选择Pachage Presentation(包呈现) 3.选择Hierarchical(分层)