Cf#595 (Div. 3)D-贪心

博客探讨了如何使用贪心算法解决Codeforces第595场(Div. 3)D题,即在保持最多k次覆盖的情况下,确定最小的线段删除数量。在Easy版本中,通过差分数组和前缀和实现;而在Hard版本中,由于点的数量增加,需要预处理边的信息,维护一个集合和覆盖次数变量,以更高效地找到需要删除的边。
摘要由CSDN通过智能技术生成

1249D1 - Too Many Segments (easy version)
1249D2 - Too Many Segments (hard version)
题意:给n条平行线段,区间被线段覆盖,问:使所有点上最多有k次覆盖,最少需要删除多少条边。
贪心的思路:从最左(点1)向右找当一个点被覆盖超过k,找到覆盖它的线段,删除右端点最远的线段,如果还超过k,再继续删除。
easy版本一共只有200个点,用差分再求前缀得到点上被覆盖线段的数量,每到一个点遍历所有的边以找到要删除的边。删除这条边后还要在数组l-r中删除1。
hard版本有 2 e 5 2e5 2e5个点,不能直接遍历。但我们仍需要找到覆盖到某一点的边,和点当前的覆盖次数。预存储每个点以它为起始点的边号,和到它就结束的边边号(比如一条直线是(2,5),我们需要在2点存下这条边,再在6点存下,打上标记区分,题中有(2,2)的这种边,所以加入我们在点2存表示开始和结束的不能达到我们接下来要的效果)。不过依然从最左边点开始,将以该点为起始点的边加入到 s e t < i n t > s e g t set<int> segt set<int>segt中,在删除以它为结束点的边(边(2,3),在点4时把他删除,这就是为什么这样存的作用了)(保证segt中的边都是覆盖这个点的),以及一个变量subcur,和一个数组sub。当我们删除一条边(l,r)时,subcur++,sub[r+1] − − -- ,前缀数组 − - subcur就可以表示点的覆盖次数。sub数组的作用是维护subcur,当(l,r)线段被删除后,只有l-r的覆盖改变,所有到遍历到r+1点时,需要subcur+sub[r+1]。

hard版本

#include<iostream>
#include<stdio.h>
#include<algorithm>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值