题解 bzoj 2151 种树
题意
手写堆大法好啊,题解貌似没有结构体堆的做法,思路有些像配对堆,关于配对堆请自行百度,因为本蒟蒻不会。。
以下是蒟蒻的做法:建立一个大根堆a维护最大价值里面存入它的编号以及价值。听说配对堆可以不用定义结构体,但我不会呀!l表示这个位置左边的编号,r同理。一个数组book标记是否可以选择,每次选完之后左右两边进行标记,堆中加入左右之和减去本身的值再将其放入原来的位置,即可达到后悔操作,更新左右编号,然后取m次即可。
#include<bits/stdc++.h>
using namespace std;
int n,m,add,k;
struct node{
int data;//价值
int num;//编号
}a[200010];
int c[200010];
int l[200010],r[200010];
bool book[200010];
long long ans;
void shiftdown(int x){//下调操作,依靠价值进行堆中元素调整
int t,flag=0;
while(2*x<=add&&flag==0){
if(a[x].data<a[2*x].data) t=2*x;
else t=x;
if(2*x+1<=add&&a[t].data<a[2*x+1].data) t=2*x+1;
if(t!=x){
swap(a[t],a[x]);//这里是交换结构体哦
x=t;
}else flag=1;
}
}
void shiftup(int x){//上调操作
int flag=0;
if(x==1) return;
while(x!=1&&flag==0){
if(a[x].data>a[x/2].data) swap(a[x],a[x/2]);
else flag=1;
x/=2;
}
}
int main(){
scanf("%d %d",&n,&m);
if(m>(n>>1)){
printf("Error!");
return 0;
}
for(int i=1;i<=n;++i){
scanf("%d",&c[i]);
a[++add].data=c[i];
a[add].num=i;
l[i]=i-1;
r[i]=i+1;
shiftup(add);//每加入一个新的元素都要进行上调操作
}
l[1]=n,r[n]=1;//环形的
ans=0;
while(m--){//标记过的直接弹出
int x=a[1].num,val=a[1].data;
a[1]=a[add--];
shiftdown(1);
while(book[x]){//注意先把值取出来再弹出哦
x=a[1].num,val=a[1].data;
a[1]=a[add--];
shiftdown(1);
}
ans+=val;
c[x]=c[l[x]]+c[r[x]]-c[x];//左右减去本身
book[l[x]]=1;//标记
book[r[x]]=1;
l[x]=l[l[x]];//新的左边的原来左边的左边
r[x]=r[r[x]];//大体同上
r[l[x]]=x;//左边的右边更新
l[r[x]]=x;//右边的左边更新
a[++add].data=c[x];
a[add].num=x;//放入元素
shiftup(add);
}
printf("%lld",ans);
return 0;
}
题解 bzoj 2151 种树的更多相关文章
- [bzoj 2151]种树(贪心)
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2151 分析:原型是bzoj 1150(CTSC 2007) 首先DP无法下手,想到贪心.想到贪 ...
- BZOJ 2151 种树(循环链表)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2151 [题目大意] 在一个长度为n的数字环中挑选m个不相邻的数字使得其和最大 [题解] ...
- 【刷题】BZOJ 2151 种树
Description A城市有一个巨大的圆形广场,为了绿化环境和净化空气,市政府决定沿圆形广场外圈种一圈树.园林部门得到指令后,初步规划出n个种树的位置,顺时针编号1到n.并且每个位置都有一个美观度 ...
- bzoj 2151 种树——贪心+后悔
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2151 似乎是半年+前讲过的.(然而看到的时候却不会了) 考虑贪心,限制就是不能选两边的.如果 ...
- bzoj 2151 种树 —— 思路+链表
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2151 先都放进堆里取最大的,但选了一个就不能选它两边的,所以可能不是最优,要有“反悔”的措施 ...
- BZOJ 2151 种树
贪心+priority_queue. #include<iostream> #include<cstdio> #include<cstring> #include& ...
- bzoj 2151: 种树【贪心+堆】
和数据备份差不多 设二元组(i,a[i]),开一个大根堆把二元组塞进去,以len排序,每次取出一个二元组 因为单纯的贪心是不行的,所以设计一个"反悔"操作. 记录二元组的前驱pr后 ...
- Guard Duty (medium) Codeforces - 958E2 || (bzoj 2151||洛谷P1792) 种树 || 编译优化
https://codeforces.com/contest/958/problem/E2 首先求出N个时刻的N-1个间隔长度,问题就相当于在这些间隔中选K个数,相邻两个不能同时选,要求和最小 方法1 ...
- 【BZOJ 2151】 2151: 种树 (贪心+堆+双向链表)
2151: 种树 Description A城市有一个巨大的圆形广场,为了绿化环境和净化空气,市政府决定沿圆形广场外圈种一圈树.园林部门得到指令后,初步规划出n个种树的位置,顺时针编号1到n.并且每个 ...
随机推荐
- 2019上半年总结——Github上那些Java面试、学习相关仓库
分享一下最近逛Github看到了一些对于Java面试以及学习有帮助的仓库,这些仓库涉及Java核心知识点整理.Java常见面试题.算法.基础知识点比如网络和操作系统等等. 知识点相关 1.JavaGu ...
- 【JDK】JDK源码分析-AbstractQueuedSynchronizer(2)
概述 前文「JDK源码分析-AbstractQueuedSynchronizer(1)」初步分析了 AQS,其中提到了 Node 节点的「独占模式」和「共享模式」,其实 AQS 也主要是围绕对这两种模 ...
- Adapter适配器模式--图解设计模式
第二章: Adapter 模式 Adapter模式分为两种: 1.类适配器模式 2.委托适配器 我看的是<图解设计模式>这本书,这小鬼子说的话真难懂,只能好好看代码理解. 先说适配器模式要 ...
- oracle 删除用户,提示“无法删除当前已连接的用户”
1. 首先查询出该用户的登录情况,注意用户名必须是大写 SQL> select username,sid,serial# from v$session where username = 'XST ...
- Go和Python学习计划
计划虽然不一定能实现,但还是要有的,万一实现了呢. 一.学习Go 1.先看尚雪谷https://www.bilibili.com/video/av48141461/?p=12的go语言全套,把基础的过 ...
- 关于stm32f1使用ST官方DSP库中的FFT方法
先分享一下ST官方基于F1的DSP固件库,自从ST推出F4系列的DSP固件库之后,网上好像很难找到原来F1系列的DSP固件库了. 链接:https://pan.baidu.com/s/1S5h2Ti3 ...
- 如何获取app中的toast
前言 Toast是什么呢?在这个手机飞速发展的时代,app的种类也越来越多,那们在日常生活使用中,经常会发现,当你在某个app的输入框输入非法字符或者非法执行某个流程时,经常看到系统会给你弹出一个黑色 ...
- (三十)c#Winform自定义控件-文本框(三)
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...
- JVM面试十问
1. JVM运行时划分哪几个区域?哪些区域是线程共享的?哪些区域是线程独占的? JVM运行时一共划分:程序计数器.虚拟机栈.堆.本地方法栈.方法区. 线程共享的数据区域:堆.方法区. 线程独享的数据区 ...
- Netty源码分析--内存模型(下)(十二)
这一节我们一起看下分配过程 PooledByteBuf<T> allocate(PoolThreadCache cache, int reqCapacity, int maxCapacit ...