小小粉丝度度熊

 

链接:http://acm.hdu.edu.cn/showproblem.php?pid=6119

Problem Description
度度熊喜欢着喵哈哈村的大明星——星星小姐。

为什么度度熊会喜欢星星小姐呢?

首先星星小姐笑起来非常动人,其次星星小姐唱歌也非常好听。

但这都不是最重要的,最重要的是,星星小姐拍的一手好代码!

于是度度熊关注了星星小姐的贴吧。

一开始度度熊决定每天都在星星小姐的贴吧里面签到。

但是度度熊是一个非常健忘的孩子,总有那么几天,度度熊忘记签到,于是就断掉了他的连续签到。

不过度度熊并不是非常悲伤,因为他有m张补签卡,每一张补签卡可以使得某一忘签到的天,变成签到的状态。

那么问题来了,在使用最多m张补签卡的情况下,度度熊最多连续签到多少天呢?

 

Input
本题包含若干组测试数据。

第一行两个整数n,m,表示有n个区间,这n个区间内的天数,度度熊都签到了;m表示m张补签卡。

接下来n行,每行两个整数(l[i],r[i]),表示度度熊从第l[i]天到第r[i]天,都进行了签到操作。


数据范围:

1<=n<=100000

0<=m<=1000000000
0<=l[i]<=r[i]<=1000000000


注意,区间可能存在交叉的情况。
 

Output
输出度度熊最多连续签到多少天。
 

Sample Input
2 1
1 1
3 3
1 2
1 1
 

Sample Output
3
3

Hint

样例一:度度熊补签第2天,然后第1天、第二天和第三天都进行了签到操作。
样例二:度度熊补签第2天和第3天。
 
 
题干

就是一道模拟题,不知被撒旦诅咒了还是咋的,写了好几种代码都没对,还耗费了一下午(倒是练习了一题多解,也提升了打代码的能力)

  思路一:维护一个先进先出的队列,每当有空隙时,就让m减小,当M不能填补空洞时,出队M加前面的空洞长。对每一个队列的长取max。

  思路二:把重叠区间合并,生成一个新数组gap[]表示  每个空区间的长度。算是一种简化吧。

#include<iostream>
#include<cstdio>
#include<string>
#include<cmath>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
#define LL long long 
#define M 100005
int gap[M];
struct node{
    LL l,r;
}a[M],b[M];
LL n,m;
bool cmp(node u,node v)
{
  if(u.l==v.l) return u.r>v.r;
  return u.l<v.l;
}
int main()
{
    while(scanf("%lld%lld",&n,&m)!=EOF)
    {
        for(int i=1;i<=n;i++)
            scanf("%lld%lld",&a[i].l,&a[i].r);
        sort(a+1,a+1+n,cmp);
        int tot=1;
        b[tot]=a[1];
        for(int i=2;i<=n;i++)
        {
            if(a[i].l<=b[tot].r+1)    b[tot].r=max(b[tot].r,a[i].r);
            else b[++tot]=a[i];
        }
        for(int i=1;i<=tot;i++)
            gap[i]=b[i+1].l-b[i].r-1;
        LL used=0,l=1;
        LL ans=b[1].r-b[1].l+1+m;
        for(int i=1;i<tot;i++)
        {
            used+=gap[i];
            while(used>m)    used-=gap[l++];
            ans=max(ans,b[i+1].r-b[l].l+1+m-used);
        }
        printf("%lld
",ans);        
    }
    return 0;
}
代码
原文地址:https://www.cnblogs.com/CLGYPYJ/p/7383714.html