您的位置:首页 > 其它

2017百度之星初赛B-1006-小小粉丝度度熊(尺取)

2017-08-14 09:22 295 查看

小小粉丝度度熊

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 784    Accepted Submission(s): 234


[align=left]Problem Description[/align]
度度熊喜欢着喵哈哈村的大明星——星星小姐。

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

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

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

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

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

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

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

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

 

[align=left]Input[/align]
本题包含若干组测试数据。

第一行两个整数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

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

[align=left]Output[/align]
输出度度熊最多连续签到多少天。

 

[align=left]Sample Input[/align]

2 1
1 1
3 3
1 2
1 1

 

[align=left]Sample Output[/align]

3
3

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

 

Source

一个简单的尺取题,坑点我觉得只有区间重叠这一部分,尺取之前处理一下就好了,其他没什么坑点,然而比赛时竟wa了一个半小时没找到错误,发现是指针移动次序出现问题,哇。。。难受。

#include<map>
#include<stack>
#include<queue>
#include<vector>
#include<math.h>
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
typedef __int64 ll;
#define inf 1000000000
#define MOD 1000000007
#define maxn 105000
#define lowbit(x) (x&-x)
#define eps 1e-10
struct node
{
ll l,r;
}a[maxn];
ll b[maxn];
bool comp(node a,node b)
{
if(a.l==b.l)
return a.r<b.r;
return a.l<b.l;
}
int main(void)
{
ll n,m,i,j,ans,p,q;
FILE *fp;
//fp=fopen("D:\\1111.txt","r");
while(scanf("%I64d%I64d",&n,&m)!=EOF)
{
ans=0;
for(i=1;i<=n;i++)
scanf("%I64d%I64d",&a[i].l,&a[i].r);
sort(a+1,a+n+1,comp);
for(i=2;i<=n;i++)
{
if(a[i].l<=a[i-1].r)
a[i].l=a[i-1].r+1;
if(a[i].r<a[i].l)
a[i].r=a[i].l-1;
}
b[1]=a[1].l-1;
if(b[1]<0)b[1]=0;
for(i=2;i<=n;i++)
b[i]=max(0ll,a[i].l-a[i-1].r-1);
p=1;ll sum=0,sm=0;
for(i=1;i<=n;i++)
{
ans=max(ans,sm+m);
sm+=a[i].r-a[i].l+1;
sum+=b[i];
while(sum>m)
{
sum-=b[p];
if(p!=1)
sm-=(a[p-1].r-a[p-1].l+1);
p++;
if(sum<=m)
break;
}
}
ans=max(a[1].r-a[1].l+1+m,ans);
ans=max(ans,sm+m);
printf("%I64d\n",ans);
}
//fclose(fp);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: