CodeForces - 612D (排序+区间计数+扫描线 区间覆盖)

题目链接:http://codeforces.com/problemset/problem/612/D


题目大意:

给出n条线段,让你算这些线段重合次数大于等于k次的部分


输入: 

第一行:给出两个数n  k      分别表示要输入的线段个数和所需的线段最少重叠次数

接下来n行 每行一个l  r表示线段的左端点和右端点。


解题思路:

至于这道题:区间覆盖问题 ,先把所有线段进行处理

对于每条线段e ,对于左端点,将值记下并且标记为0存入结构体数组,右端点将 值 记下标记为1存入结构体数组

然后让值从小到大对结构体排序,若值相同将0排在前面(过一会你就知道为什么了)


这样处理后共有2*n个点,定义一个变量cnt记录贡献值

当遇到标记为1时--cnt表示这次之后这点被覆盖了cnt次

遇到标记为0时++cnt;  表示这次之后这点被覆盖了cnt次

当cnt增加到k时就要将这个点作为覆盖k次的左端点,

当cnt减少到k-1时就要把这个点作为覆盖k次结束的右端点


前面提到若值相同将则将标记为0的排在前面,是为了下面这样的数据  

3   2

0 10

0 5

5 10

因为将左端点排在左边 才能将0 5 ,5 10这样的区间看作一个区间(因为cnt是先加后减的)

代码:


#include
#include
#include
#include
#include
#include
#include
#include
#define N 1010000
#define INF 0x3f3f3f3f
#define MOD 100007
using namespace std;
struct node
{
    int d,sign;
} e[2*N];
bool cmp(node q,node qq)
{
    if(q.d==qq.d)
        return q.sign

你可能感兴趣的:(其他题目/思维/贪心)