bzoj 1367 [ Baltic 2004 ] sequence —— 左偏树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1367
好题啊!论文上的题;
论文上只给出了不下降序列的求法:
先考虑特殊情况,如果原序列上升,那么答案序列相同即可,如果下降,那么答案序列取中位数;
那么对于跌宕起伏的原序列,可以先一个一个加入元素,每次加入一个作为一个新区间,中位数是自己;
因为答案序列要不下降,所以当前区间的中位数比前一个区间大的时候就要合并,归纳可知(感性理解)整个区间的答案是它们的中位数;
论文中有严谨证明:https://wenku.baidu.com/view/20e9ff18964bcf84b9d57ba1.html
取中位数可以用一个大小是全体一半的大根堆,又要合并,所以就用可并堆;
那么求上升序列呢?
有个很巧妙的技巧,就是把原序列 t[i] = t[i] - i,然后对于这个序列求不下降序列;
那么得到答案序列后,把答案序列的每个元素都 + i,就得到一个上升序列,而差值的和还是不变的。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int const maxn=1e6+;
int n,t[maxn],l[maxn],r[maxn],rt[maxn],siz[maxn],num[maxn];
int ls[maxn],rs[maxn],dis[maxn];
ll ans;
int abb(int x){return x>?x:-x;}
int merge(int x,int y)
{
if(!x||!y)return x+y;
if(t[x]<t[y])swap(x,y);//维护大根堆
rs[x]=merge(rs[x],y);
siz[x]=siz[ls[x]]+siz[rs[x]]+;//+1
if(dis[ls[x]]<dis[rs[x]])swap(ls[x],rs[x]);
if(rs[x])dis[x]=dis[rs[x]]+;
else dis[x]=;
return x;
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)scanf("%d",&t[i]),t[i]-=i;
int nw=;
for(int i=;i<=n;i++)
{
l[++nw]=r[nw]=i; rt[nw]=i;
siz[rt[nw]]=num[nw]=;
while(nw>&&t[rt[nw-]]>t[rt[nw]])
{
nw--;
num[nw]+=num[nw+]; r[nw]=r[nw+];
rt[nw]=merge(rt[nw],rt[nw+]);
while(siz[rt[nw]]*>num[nw]+)//+1
rt[nw]=merge(ls[rt[nw]],rs[rt[nw]]);
}
}
for(int i=;i<=nw;i++)
for(int j=l[i];j<=r[i];j++)ans+=abb(t[j]-t[rt[i]]);
printf("%lld\n",ans);
return ;
}
bzoj 1367 [ Baltic 2004 ] sequence —— 左偏树的更多相关文章
- bzoj1367 [Baltic2004]sequence 左偏树+贪心
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=1367 题解 先考虑条件为要求不下降序列(不是递增)的情况. 那么考虑一段数值相同的子段,这一段 ...
- BZOJ 2809: [Apio2012]dispatching(左偏树)
http://www.lydsy.com/JudgeOnline/problem.php?id=2809 题意: 思路:最简单的想法就是枚举管理者,在其子树中从薪水低的开始选起,但是每个节点都这样处理 ...
- BZOJ 4003: [JLOI2015]城池攻占 左偏树 可并堆
https://www.lydsy.com/JudgeOnline/problem.php?id=4003 感觉就是……普通的堆啊(暴论),因为这个堆是通过递归往右堆里加一个新堆或者新节点的,所以要始 ...
- 【BZOJ1367】[Baltic2004]sequence 左偏树
[BZOJ1367][Baltic2004]sequence Description Input Output 一个整数R Sample Input 7 9 4 8 20 14 15 18 Sampl ...
- bzoj 4003 [JLOI2015]城池攻占 —— 左偏树
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4003 其实蛮简单的,首先一个城市只会被其子树中的骑士经过,启发我们 dfs 序用可并堆合并子 ...
- BZOJ1367: [Baltic2004]sequence(左偏树)
Description Input Output 一个整数R Sample Input 7 9 4 8 20 14 15 18 Sample Output 13 解题思路: 有趣的数学题. 首先确定序 ...
- 【BZOJ 1367】 1367: [Baltic2004]sequence (可并堆-左偏树)
1367: [Baltic2004]sequence Description Input Output 一个整数R Sample Input 7 9 4 8 20 14 15 18 Sample Ou ...
- 黄源河《左偏树的应用》——数字序列(Baltic 2004)
这道题哪里都找不到. [问题描述] 给定一个整数序列a1, a2, … , an,求一个不下降序列b1 ≤ b2 ≤ … ≤ bn,使得数列{ai}和{bi}的各项之差的绝对值之和 |a1 - b1| ...
- 洛谷P4331 [BOI2004] Sequence 数字序列 [左偏树]
题目传送门 数字序列 题目描述 给定一个整数序列 a1,a2,⋅⋅⋅,an ,求出一个递增序列 b1<b2<⋅⋅⋅<bn ,使得序列 ai 和 bi 的各项之差的绝对 ...
随机推荐
- vue基础---Class 与 Style 绑定
[一]绑定HTML Class (1)对象语法 ①普通绑定class <div id="area" v-bind:class="className"> ...
- react-router 4.x 路由按需加载
react-router 4 代码分割(按需加载) 官方文档 https://serverless-stack.com/chapters/code-splitting-in-create-react ...
- 【转载】linux下的zookeeper启动
zookeeper的安装目录:/usr/local/zookeeper-3.4.6/bin/zkServer.sh; 配置文件路径:../conf/zoo.cfg 端口 :2181: ZooKeepe ...
- TestNG忽略测试
用@Test(enabled = false) 声明需要被忽略执行的测试方法 package com.janson; import org.testng.annotations.Test; publi ...
- centos7修改时间和时区
设置时区同样, 在 CentOS 7 中, 引入了一个叫 timedatectl 的设置设置程序. 用法很简单: # timedatectl # 查看系统时间方面的各种状态 Local time: 四 ...
- Python学习——字典
字典 字典是另一种可变容器模型,且可存储任意类型对象. 1.创建字典 字典由键和对应值成对组成.每个键与值之间用:隔开,每对之间逗号隔开. 每个键应当互不相同,值可以相同.若同时出现两个相同的键,则后 ...
- x component of 2nd stokes wave--- C code
* Source code The following is a C code for x component of 2nd stokes wave ××××××××××××××××××××× /*s ...
- Tclientdate的排序
CDS_common.IndexDefs.Clear; CDS_common.AddIndex('JSPH','JSPH',[],'JSPH'); CDS_common.A ...
- String类的转换功能
/* * String类的转换功能 * char[] toCharArray():把字符串转换为字符数组 * String toLowerCase():把字符串转换为小写字符串 * String to ...
- spring-boot | 整合通用Mabatis 分页插件PageHelper
Mybatis通用Mapper介绍 Mybatis 通用 Mapper 极其方便的使用 Mybatis 单表的增删改查,支持单表操作,不支持通用的多表联合查询 优点: 通用 Mapper 可以极大的方 ...