原题传送门

思路

这题直接模拟过即可,根本不需要什么线段树。

仔细看数据范围,发现仅仅是$1\le n\le 5000,0\le l\le r\le 10^{6} $。

于是暴力也能过。

储存每个人的时间建议用结构体,里面放开始时间和结束时间。

因为范围特别小,所以用一个数组来储存这一秒有没有人挤奶。

然后再将每一段挤奶时间的秒数放进一个数组里排一下序,输出最大的即可。

最短空闲时间如法炮制即可。

要注意求每一段挤奶时间的秒数时要从最开始挤奶的时间枚举到最后挤奶的时间,否则会爆炸。

AC代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include<bits/stdc++.h>
using namespace std;
int n,minn=1145141919,ll=-1,maxn=-1,rr=1,s[11451419],c[11451419],cc[11451419];//ll要赋成-1,因为l,r可能等于0
struct node{
int l,r;
}a[114514];//结构体
bool cmp(int x,int y){
return x>y;
}//cmp函数
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i].l>>a[i].r;
maxn=max(maxn,a[i].r);
minn=min(minn,a[i].l);//求最开始挤奶的时间和最后挤奶的时间
for(int j=a[i].l;j<=a[i].r;j++){
s[j]=1;//用一个数组将那些时间挤奶存起来
}
}
for(int i=minn;i<=maxn+1;i++){
if(s[i]==1){
if(ll<0)
ll=i;//这一段开始的时间
}
else if(ll>=0){
c[rr]=i-ll-1;
rr++;
ll=-1;//如果遇到0就代表这一段结束,将秒数存起来
}
}//求每一段挤奶时间的秒数
rr=1;
ll=-1;
for(int i=minn;i<=maxn;i++){
if(s[i]==0){
if(ll<0)
ll=i;
}
else if(ll>=0){
cc[rr]=i-ll+1;
rr++;
ll=-1;
}
}//将每一段非挤奶的时间存起来
sort(c+1,c+maxn+1,cmp);
sort(cc+1,cc+maxn+1,cmp);//排序
cout<<c[1]<<" "<<cc[1];//输出
}