2021.08.01 P4311 数字序列(左偏树)
2021.08.01 P4311 数字序列(左偏树)
[P4331 BalticOI 2004]Sequence 数字序列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
重点:
1.对于左偏树的应用
2.好好复习一下高中数学必修三
题意:
给定一个整数序列a_1, a_2, ··· , a_n,求出一个递增序列b_1 < b_2 < ··· < b_n,使得序列a_i和b_i的各项之差的绝对值之和|a_1 - b_1| + |a_2 - b_2| + ··· + |a_n - b_n|最小。
分析:
当求一个数x,使得a[1],a[2]…,a[n]最小,这个数为这n个数的中位数。
代码如下:
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e6+10;
typedef long long ll;
int n,top,array[N],ansi[N],vis[N],fa[N];
ll ans;
struct node{
ll val;
int rs,ls,rt,size;
}ai[N];
struct nodei{
ll val;
int ls,rs,dis;
}a[N];
inline int read(){
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')w=-1;
ch=getchar();
}
while(ch<='9'&&ch>='0'){
s=s*10+ch-'0';
ch=getchar();
}
return s*w;
}
int find(int x){
return fa[x]==x?x:fa[x]=find(fa[x]);
}
int merge(int x,int y){
if(!x||!y)return x+y;
if(array[x]==array[y]?x>y:array[x]<array[y])swap(x,y);
//既然要求递增,那肯定是大根堆
//而且要求在尽可能早的位置元素尽可能的小,如果合并,肯定从后开始删除对顶元素
a[x].rs=merge(a[x].rs,y);
if(a[a[x].ls].dis<a[a[x].rs].dis)swap(a[x].ls,a[x].rs);
fa[x]=fa[a[x].ls]=fa[a[x].rs]=x;
a[x].dis=a[a[x].rs].dis+1;
return x;
}
void pop(int x){
vis[x]=1;
fa[a[x].ls]=a[x].ls;fa[a[x].rs]=a[x].rs;
fa[x]=merge(a[x].ls,a[x].rs);
a[x].ls=a[x].rs=a[x].dis=0;
}
int main(){
n=read();
for(int i=1;i<=n;i++){
a[i].val=array[i]=read()-i;fa[i]=i;
//ansi[i]=1;
}
a[0].dis=-1;
/*for(int i=1;i<n;i++){
int x=find(i);
fa[x]=merge(x,i+1);
}
for(int i=1;i<=n;i++)
cout<<i<<" ls "<<a[i].ls<<" rs "<<a[i].rs<<" val "<<a[i].val<<" id "<<a[i].id<<" dis "<<a[i].dis<<endl;
cout<<endl;*/
//每一个x位置的最小值是包含i的这一堆中的最小值
// 尝试找最长上升子序列
/*for(int i=1;i<=n;i++){
for(int j=1;j<i;j++)if(ai[j]<ai[i])ansi[i]=max(ansi[i],ansi[j]+1);
}
for(int i=1;i<=n;i++)cout<<ansi[i]<<" ";
cout<<endl<<endl;*/
//没用
//运用中位数知识,中位数必须递增,否则和前一个小区间合并
for(int i=1;i<=n;i++){
++top;
ai[top].ls=ai[top].rs=ai[top].rt=i;ai[top].size=1;
ai[top].val=array[i];
while(top>1&&ai[top].val<ai[top-1].val){
//合并区间
--top;
ai[top].rt=merge(ai[top].rt,ai[top+1].rt);
ai[top].size+=ai[top+1].size;
ai[top].rs=ai[top+1].rs;
while(ai[top].size*2>ai[top].rs-ai[top].ls+2){//严格的中位数
//size>(rs-ls+1)/2->size*2>rs-ls+1
//当rs-ls+1为偶数时,取偏后的数为中位数
//当rs-ls+1为奇数时,向上取整
--ai[top].size;
ai[top].rt=merge(a[ai[top].rt].ls,a[ai[top].rt].rs);
//简易版pop:不断删去堆顶的中位数
}
ai[top].val=array[ai[top].rt];
}
/*for(int j=1;j<=n;j++)
cout<<j<<" ls "<<a[j].ls<<" rs "<<a[j].rs<<" dis "<<a[j].dis<<" val "<<a[j].val<<endl;
cout<<endl<<endl;*/
}
/*for(int i=1;i<=top;i++)
cout<<i<<" ls "<<ai[i].ls<<" rs "<<ai[i].rs<<" rt "<<ai[i].rt<<" val "<<ai[i].val<<endl;
cout<<endl;*/
for(int i=1;i<=top;i++)for(int j=ai[i].ls;j<=ai[i].rs;j++){
ansi[j]=ai[i].val;
ans+=abs(ai[i].val-array[j]);
}
cout<<ans<<endl;
for(int i=1;i<=n;i++)cout<<ansi[i]+i<<" ";
return 0;
}
2021.08.01 P4311 数字序列(左偏树)的更多相关文章
- 洛谷P4331 [BOI2004] Sequence 数字序列 [左偏树]
题目传送门 数字序列 题目描述 给定一个整数序列 a1,a2,⋅⋅⋅,an ,求出一个递增序列 b1<b2<⋅⋅⋅<bn ,使得序列 ai 和 bi 的各项之差的绝对 ...
- 洛谷$P4331\ [BOI2004]\ Sequence$ 数字序列 左偏树
正解:左偏树 解题报告: 传送门$QwQ$ 开始看到的时候$jio$得长得很像之前做的一个$dp$,,, 但是$dp$那题是说不严格这里是严格? 不难想到我们可以让$a_{i},b_{i}$同时减去$ ...
- Luogu P4331 [BOI2004]Sequence 数字序列 (左偏树论文题)
清晰明了%%% Fairycastle的博客 个人习惯把size什么的存在左偏树结点内,这样在外面好写,在里面就是模板(只用修改update). 可以对比一下代码(好像也差不多-) MY CODE # ...
- 2021.08.01 P3377 左偏树模板
2021.08.01 P3377 左偏树模板 P3377 [模板]左偏树(可并堆) - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) #include<iostream> ...
- 黄源河《左偏树的应用》——数字序列(Baltic 2004)
这道题哪里都找不到. [问题描述] 给定一个整数序列a1, a2, … , an,求一个不下降序列b1 ≤ b2 ≤ … ≤ bn,使得数列{ai}和{bi}的各项之差的绝对值之和 |a1 - b1| ...
- [BOI2004]Sequence 数字序列(左偏树)
PS:参考了黄源河的论文<左偏树的特点及其应用> 题目描述:给定一个整数序列\(a_1, a_2, - , a_n\),求一个递增序列\(b_1 < b_2 < - < ...
- 2021.08.01 P4359 伪光滑数(二叉堆)
2021.08.01 P4359 伪光滑数(二叉堆) [P4359 CQOI2016]伪光滑数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 题意: 若一个大于 11 的整数 MM ...
- 【BZOJ 1367】 1367: [Baltic2004]sequence (可并堆-左偏树)
1367: [Baltic2004]sequence Description Input Output 一个整数R Sample Input 7 9 4 8 20 14 15 18 Sample Ou ...
- 【左偏树+贪心】BZOJ1367-[Baltic2004]sequence
[题目大意] 给定一个序列t1,t2,...,tn ,求一个递增序列z1<z2<...<zn , 使得R=|t1−z1|+|t2−z2|+...+|tn−zn| 的值最小.本题中,我 ...
随机推荐
- 嵌入式Linux应用开发完全手册之环境搭建
@ 目录 0.下载源配置 1.电脑BIOS启动虚拟化 2.linux网卡查看与IP设置 3.windows NAT虚拟网络配置 4.修改 Ubuntu 的 mountd 端口 5.vim设置 6.Mo ...
- 小白都能看懂的 Spring 源码揭秘之Spring MVC
目录 前言 Spring MVC 请求流程 Spring MVC 两大阶段 初始化 HttpServletBean#init() FrameworkServlet#initServletBean Fr ...
- Spring---Spring专题(二)
1.Spring配置数据源 1.1 数据源(连接池)的作用 数据源(连接池)是提高程序性能而出现的 事先实例化数据源,初始化部分链接资源 使用连接资源时从数据源中获取 使用完毕后将连接资源归还给数据源 ...
- 什么是 Netflix Feign?它的优点是什么?
Feign 是受到 Retrofit,JAXRS-2.0 和 WebSocket 启发的 java 客户端联编程序. Feign 的第一个目标是将约束分母的复杂性统一到 http apis,而不考虑其 ...
- Where和having都是条件筛选关键字,它们有什么分别?
WHERE是在数据分组前进行条件过滤, HAVING子句是在数据分组后进行条件过滤,WHERE子句中不能使用聚合函数,HAVING子句可以使用聚合函数. 需要注意说明:当同时含有where子句.gro ...
- mac idea
sout :按Tab或Enter都可以出现
- Oracle数据库 如何根据某个字段名的值去查询存在的表列表
declare v_sql varchar2(1000); data_count number; begin -- OWNER是模式名 tablespace_name是表空间 for cur_tabl ...
- redis 持久化有几种方式?
面试题 redis 的持久化有哪几种方式?不同的持久化机制都有什么优缺点?持久化机制具体底层是如何实现的? 面试官心理分析 redis 如果仅仅只是将数据缓存在内存里面,如果 redis 宕机了再重启 ...
- 解释 Spring 框架中 bean 的生命周期?
Spring 容器 从 XML 文件中读取 bean 的定义,并实例化 bean. Spring 根据 bean 的定义填充所有的属性. 如果 bean 实现了 BeanNameAware 接口,Sp ...
- 您对 Distributed Transaction 有何了解?
分布式事务是指单个事件导致两个或多个不能以原子方式提交的单独数据源的突 变的任何情况.在微服务的世界中,它变得更加复杂,因为每个服务都是一个工 作单元,并且大多数时候多个服务必须协同工作才能使业务成功 ...