P1250 种树

这里主要补充一个\(O(h\log n)\)的做法。

我们将需求看做线段,第\(i\)条线段左右端点分别是\(l_i,r_i\),要种\(cnt_i\)棵树。

那么可以使用贪心的思想求解。将线段按左端点从大到小排序,遍历每条线段\(i\):

  • 如果线段\(i\)中树的棵数\(s_i\ge cnt_i\),那么跳过即可。
  • 如果线段\(i\)中树的棵树\(s_i<cnt_i\),那么我们需要从\(l_i\)开始,找到空位就种,直到\(s_i=cnt_i\)为止。

如果朴素遍历,这一步骤的时间复杂度是\(O(hn)\)。

但是,在第二种情况下,如果我们可以快速找出一个位置\(k\),使得\([l_i,k]\)中恰好有\(cnt_i-s_i\)个空位,那么我们就可以直接利用线段树的区间赋值一次性把这些树种好(种好为\(1\),没种好为\(0\))。

为了计算\(k\),我们先考虑如何计算从下标\(1\)开始的第\(k\)个空位出现的位置。

可以使用线段树+二分,单次时间复杂度为\(O(\log^2 n)\)。

如果我们把二分挪到线段树上(线段树上二分),单次时间复杂度将降至\(O(\log n)\),代码如下:

int kth0(int x,int k,int l,int r){//查询从下标l开始,第k个0的位置
if(l==r) return l;
pushdown(x,l,r);
int mid=(l+r)>>1,lef0=mid-l+1-sum[lc];//lef0表示左子树中0的个数
if(lef0>=k) return kth0(lc,k,l,mid);
else return kth0(rc,k-lef0,mid+1,r);
}
点击查看代码
#include<bits/stdc++.h>
#define N 30010
#define H 5010
using namespace std;
int n,h,ans;
struct SEG{
#define lc (x<<1)
#define rc (x<<1|1)
int sum[N<<2],tag[N<<2];
void pushup(int x){sum[x]=sum[lc]+sum[rc];}
void pushdown(int x,int l,int r){
if(!tag[x]) return;
int mid=(l+r)>>1;
sum[lc]=(mid-l+1)*tag[x],sum[rc]=(r-mid)*tag[x];
tag[lc]=tag[rc]=tag[x],tag[x]=0;
}
int kth0(int x,int k,int l,int r){
if(l==r) return l;
pushdown(x,l,r);
int mid=(l+r)>>1,lef0=mid-l+1-sum[lc];
if(lef0>=k) return kth0(lc,k,l,mid);
else return kth0(rc,k-lef0,mid+1,r);
}
void ser(int x,int a,int b,int v,int l,int r){
if(a<=l&&r<=b) return tag[x]=v,sum[x]=(r-l+1)*v,void();
pushdown(x,l,r);
int mid=(l+r)>>1;
if(a<=mid) ser(lc,a,b,v,l,mid);
if(b>mid) ser(rc,a,b,v,mid+1,r);
pushup(x);
}
int query(int x,int a,int b,int l,int r){
if(a>b) return 0;
if(a<=l&&r<=b) return sum[x];
pushdown(x,l,r);
int mid=(l+r)>>1,ans=0;
if(a<=mid) ans+=query(lc,a,b,l,mid);
if(b>mid) ans+=query(rc,a,b,mid+1,r);
return ans;
}
}tr;
struct Seg{int l,r,cnt;}a[H];
signed main(){
cin>>n>>h;
for(int i=1;i<=h;i++) cin>>a[i].l>>a[i].r>>a[i].cnt;
sort(a+1,a+1+h,[](Seg a,Seg b){return a.l>b.l;});
for(int i=1;i<=h;i++){
int sum=tr.query(1,a[i].l,a[i].r,1,n);
if(sum<a[i].cnt){
ans+=a[i].cnt-sum;
int pos=tr.kth0(1,a[i].cnt-sum+a[i].l-1,1,n);
tr.ser(1,a[i].l,pos,1,1,n);
}
}
cout<<ans<<"\n";
return 0;
}

[题解]P1250 种树的更多相关文章

  1. P1250 种树

    P1250 种树 题目描述 一条街的一边有几座房子.因为环保原因居民想要在路边种些树.路边的地区被分割成块,并被编号成1..N.每个部分为一个单位尺寸大小并最多可种一棵树.每个居民想在门前种些树并指定 ...

  2. Java实现洛谷P1250 种树 (暴力)

    P1250 种树 输入输出样例 输入 9 4 1 4 2 4 6 2 8 9 2 3 5 2 输出 5 PS: 我种最少的树,意味着我的树要最多的被利用,意味着,我的树要尽可能的靠中间种, 也就是我把 ...

  3. P1250 种树 题解

    题目描述 一条街道的一边有几座房子,因为环保原因居民想要在路边种些树,路边的居民被分割成 n 块,并被编号为 1…n.每块大小为一个单位尺寸并最多可种一棵树.每个居民想在门前种些树并指定了三个数b,e ...

  4. 题解——洛谷P1250 种树(差分约束)

    一道看一眼就知道差分约束的题目 但是最短路spfa的时候注意松弛条件是 if(dis[u]+w[i]<dis[v[i]]) dis[v[i]]=dis[u]+w[i]; 不能写成 if(dis[ ...

  5. 洛谷 P1250 种树 题解

    差分约束系统,维护前缀和,根据式子d[ b ] < = d[ e + 1 ] - t,可以看出要连e和b - 1,但占用了超级源点0,所以要把区间向后移,这样就可以用超级源点0来保持图的连通性( ...

  6. P1250 种树(差分约束 / 贪心)

    题目描述 一条街的一边有几座房子.因为环保原因居民想要在路边种些树.路边的地区被分割成块,并被编号成1-N.每个部分为一个单位尺寸大小并最多可种一棵树.每个居民想在门前种些树并指定了三个号码B,E,T ...

  7. luogu P1250 种树

    我来总结一下最常用的两种办法 1.贪心 2.差分约束 那么我们先来讲,贪心版<种树> 大家可能知道有一个题和这个类似,那个是钉钉子而这个是种树 我们可以借用钉钉子的思路来想,首先这个是让你 ...

  8. 洛谷P1250种树(贪心)

    题目描述 一条街的一边有几座房子.因为环保原因居民想要在路边种些树.路边的地区被分割成块,并被编号成1..N.每个部分为一个单位尺寸大小并最多可种一棵树.每个居民想在门前种些树并指定了三个号码B,E, ...

  9. 题解 P1484 种树

    题目 传送门 cyrcyr今天在种树,他在一条直线上挖了 n 个坑. 这n个坑都可以种树,但为了保证每一棵树都有充足的养料,cyrcyr不会在相邻的两个坑中种树. 而且由于cyrcyr的树种不够,他至 ...

  10. HDU 1384 Intervals &洛谷[P1250]种树

    差分约束 差分约束的裸题,关键在于如何建图 我们可以把题目中给出的区间端点作为图上的点,此处应注意,由于区间中被标记的点的个数满足区间加法,这里与前缀和类似,对于区间[L..R]来说,我们加入一条从L ...

随机推荐

  1. Spring注解之@Autowired组件装配

    前言 说起Spring的@Autowired注解,想必大家已经耳熟能详:对于小编而言,虽然一直知道怎么用,但是并没有去了解过,因此,本文就梳理一下@Autowired注解的功能,如有写的不准确的地方, ...

  2. C# Task 取消执行的简单封装

    我让DeepSeek帮我写了一段使用 CancellationTokenSource 取消任务的简单示例如下: 取消任务的简单示例 using System.Threading.Tasks; usin ...

  3. NAT的两种模式SNAT和DNAT介绍

    一.简单介绍 NAT(Network Address Translation):网络地址转换,是将IP数据包头中的IP地址转换为另一个IP地址的过程.在实际的应用中,NAT主要用于实现私有网络访问公共 ...

  4. C# 异步编程:从 async/await 到 Task 并行库的全面解析

    引言 在现代软件开发中,处理高并发和耗时操作是一个常见的挑战.C# 提供了强大的异步编程模型,它允许程序在执行耗时操作时不会阻塞主线程,从而提高程序的响应性和性能.其中,async/await 关键字 ...

  5. C#实现语音预处理:降噪、静音检测、自动增益(附Demo源码)

    无论是在音视频录制系统,还是音视频通话系统.或视频会议系统中,对从麦克风采集到的说话的声音数据进行预处理,都是是非常必要的. 语音数据预处理主要包括:​​降噪(Noise Reduction).静音检 ...

  6. ET5.0-添加心跳功能

    ET5.0 demo中添加心跳功能 一.服务端 1:添加文件夹,在Model/Module文件夹下新建文件夹 Hearbeat 2:添加心跳配置文件   SessionHeartbeatCompone ...

  7. Http 中所有的 data 中base64 类型

    https://blog.csdn.net/webxiaoma/article/details/70053444 一.我们在看代码时经常在img或css背景图片中看到: src="data: ...

  8. I5TING_TOC转成的HTML,怎样高亮代码

    找到安装位置全局安装一般在默认位置C:\Users\administrator\AppData\Roaming\npm\node_modules\i5ting_toc 修改marked.jsi5tin ...

  9. vue-cli3项目开启less支持并引入短链接

    说明用脚手架搭建的时候,可以在选项中开启(支持less).但是如果项目已经建好了这个时候想开启支持,就需要额外做些事情了支持less安装该插件 vue add style-resources-load ...

  10. Mysql傻瓜式安装教程,Mysql GUI SQLyog安装教程,java数据库连接JDBC(Eclipse)

    一.Mysql的安装 1.截至2022/5/22最新版mysql安装器. https://cdn.mysql.com//Downloads/MySQLInstaller/mysql-installer ...