0
点赞
收藏
分享

微信扫一扫

K金牌厨师(双条件二分+差分)

代码小姐 2022-01-26 阅读 26
c++算法

链接
二分+差分
二分最大值,check得到满足两个条件的解。(以前做的都是满足一种条件的二分,注意体会区别)
题目目的:让共同区间尽可能的长,并且共同区间数目尽可能的多。
我们每次二分得到mid,既指人数,也指长度。
然后第一个for循环记录长度满足≥mid的前缀和人数,第二个for循环差分得到符合≥mid的长度的人数,如果人数sum[i]≥mid,return true,(说明满足两个条件)。

#include<iostream>
#include<cstring>
using namespace std;
const int N=3e5+1000;
typedef pair<int,int> PII;
PII a[N];
int n,m,sum[N];
//二分最大化可行答案,对于每次mid,差分维护判断是否存在连续长度不小于mid且人数也不小于mid的区间
bool check(int mid)    //人数≥mid,长度≥mid
{
    memset(sum,0,sizeof sum);
    for(int i=0;i<m;i++)
    {
        int len=a[i].second-a[i].first+1;
        if(len>=mid)	//第一个条件
        {
            sum[a[i].first+mid-1]++;
            sum[a[i].second+1]--;
        }
    }
    
    for(int i=1;i<=n;i++)
    {
        sum[i]+=sum[i-1];
        if(sum[i]>=mid) 	//第二个条件
        	return true;
    }
    return false;
}
int main()
{
    cin>>n>>m;
    for(int i=0;i<m;i++) cin>>a[i].first>>a[i].second;
    
    int l=0,r=m-1;
    while(l<r)
    {
        int mid=(l+r+1)/2;
        if(check(mid)) l=mid;
        else r=mid-1;
    }
    
    cout<<l<<endl;
    return 0;
}
举报

相关推荐

0 条评论