金牌厨师 二分 第九届“图灵杯”NEUQ-ACM程序设计竞赛个人赛

链接:https://ac.nowcoder.com/acm/contest/27302/K
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
Phenix作为食堂的金牌厨师,每天的工作是为同学们准备饭菜,Phenix做出的每一种菜都有一个辣度值,范围是[1,n][1,n]。作为厨师,Phenix提前了解了m位同学的辣度接受范围,第i位同学的辣度接受范围被描述为[l_i,r_i][l
i

,r
i

],表示该同学可以接受辣度值位于这个区间的菜。由于众口难调,每天Phenix会选出部分同学,做出能让这部分同学都接受的辣度的菜。Phenix作为金牌厨师对每天工作的满意程度定义为选出的同学的人数kk和能让这部分同学都接受的菜的种类数xx(这里理解为一种辣度对应一种菜)两者中的最小值,即min(k,x)min(k,x)n,mn,m(1<=n,m<=300000)(1<=n,m<=300000)。

现在你需要想办法让Phenix的满意程度最大。

输入描述:
第一行两个整数n,mn,m,表示菜的辣度最大值和同学的人数(1<=n,m<=300000)(1<=n,m<=300000)。

接下来mm行,每行两个整数l_i,r_il
i

,r
i

依次表示第ii个同学的辣度接受范围(1<=l_i,r_i<=n)(1<=l
i

,r
i

<=n)

输出描述:
一行,表示满意度的最大值。
示例1
输入
复制
5 5
3 5
1 2
2 5
2 5
4 5
输出
复制
3
说明
最优策略为:选择第1,3,4位同学,他们的辣度接受范围分别是[3,5],[2,5],[2,5],所以能让他们都接受的菜的辣度是3,4,5,此时k=3,x=3,满意度=min(k,x)=3

思路 :
在这里插入图片描述
在这里插入图片描述

  • 二分不会写,呜呜呜
#include<cstdio>
#include<iostream>
#include<queue>
const int N = 3e5 + 10;
using namespace std;
struct ll{int r,last;}d[N];
int n,m,ans,num,head[N];
int read(){
 int k=0,f=0;char c=getchar();for(;c<'0'||c>'9';c=getchar())if(c=='-')f=1;
 for(;c<='9'&&c>='0';c=getchar())k=(k<<3)+(k<<1)+c-'0';return f?-k:k;
}
bool check(int x){
 int cnt = 0;priority_queue<int>q;
 for(int i = 1;i + x - 1 <= n;i ++){
  for(int t = head[i];t;t = d[t].last)
  if(d[t].r >= i + x - 1)cnt++,q.push(-d[t].r);
  while(!q.empty()&&-q.top() < i + x - 1)cnt--,q.pop();
  if(cnt >= x)return true;
 }return false;
}
void Dce(int l,int r){
 while(l <= r){
  int mid = l + r >> 1;
  if(check(mid))ans = mid,l = mid + 1;
  else r = mid - 1;
 }printf("%d\n",ans);
}
void add(int a,int b){d[++num]=(ll){b,head[a]};head[a]=num;}
int main(){
 n = read();m = read();
 for(int i = 1;i <= m;i ++){
  int a = read(),b = read();
  add(a,b);
 }
 Dce(0,min(n,m));
 return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值