金牌厨师
题意:
给定
m
m
m 个区间,每个区间在
[
1
,
n
]
[1,n]
[1,n] 之间,选出
k
k
k 个区间,这
k
k
k 个区间的交集长度为
x
x
x,定义满意度为
m
i
n
(
k
,
x
)
min(k,x)
min(k,x)
求最大满意度
思路:
显然二分最大化
具体
c
h
e
c
k
check
check 看代码好理解
非常妙的思路
code:
#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define ull unsigned long long
#define ld long double
#define all(x) x.begin(), x.end()
#define eps 1e-6
using namespace std;
const int maxn = 3e5 + 9;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
ll n, m;
/*
vector <int> R[maxn];
bool check(int x){
priority_queue <int, vector<int>, greater<int> > q;
for(int i = 1; i + x - 1 <= n; ++i){
for(auto r : R[i]) q.push(r);
while(!q.empty() && q.top() < i + x - 1) q.pop();
if(q.size() >= x) return 1;
}
return 0;
}*/
pair <int, int> a[maxn];
int c[maxn];
bool check(int x){
memset(c, 0, sizeof(c));
for(int i = 1; i <= m; ++i){
int r = a[i].first + x - 1;
if(r <= a[i].second) c[r]++, c[a[i].second + 1] --;
}
for(int i = 1; i <= n; ++i)
{
c[i] += c[i-1];
if(c[i] >= x) return 1;
}
return 0;
}
void work()
{
cin >> n >> m;
/*for(int i = 1, l, r; i <= m; ++i){
cin >> l >> r;
R[l].push_back(r);
}*/
for(int i = 1; i <= m; ++i) cin >> a[i].first >> a[i].second;
int l = 1, r = min(n, m);
while(l < r)
{
int mid = (l + r + 1) >> 1;
if(check(mid)) l = mid;
else r = mid - 1;
}
cout << r;
}
int main()
{
ios::sync_with_stdio(0);
// int TT;cin>>TT;while(TT--)
work();
return 0;
}