[题解]CF1884C Medium Design
思路
假设最后最大值的位置为 \(x\),最小值的位置为 \(y\)。
那么将所有满足 \(l_i \leq y \leq r_i\) 的线段选出来一定不优。
因为如果 \(x < l_i \vee x > r_i\) 会使答案减 \(1\);如果 \(l_i \leq x \leq r_i\) 会使答案不变。
考虑 \(y\) 的移动对答案的影响。
如果 \(x < y\),那么 \(y\) 右移一定不会使答案变劣;反之,如果 \(x > y\),那么 \(y\) 左移一定不会使答案变劣。
所以最后 \(y\) 的取值一定会是 \(1\) 或 \(m\)。
将两种情况分别计算一下即可。对于计算的时候由于是静态的问题,可以直接先离散化,然后套一个差分即可。
Code
#include <bits/stdc++.h>
#define re register
using namespace std;
const int N = 2e5 + 10;
int T,n,m;
int arr[N];
struct sec{
int l,r;
}s[N];
inline int read(){
int r = 0,w = 1;
char c = getchar();
while (c < '0' || c > '9'){
if (c == '-') w = -1;
c = getchar();
}
while (c >= '0' && c <= '9'){
r = (r << 3) + (r << 1) + (c ^ 48);
c = getchar();
}
return r * w;
}
inline void solve(){
int ans = 0;
vector<int> p;
n = read();
m = read();
for (re int i = 1;i <= n;i++){
s[i].l = read();
s[i].r = read();
p.push_back(s[i].l);
p.push_back(s[i].r + 1);
}
sort(p.begin(),p.end());
unique(p.begin(),p.end());
for (re int i = 1;i <= 2 * n;i++) arr[i] = 0;
for (re int i = 1;i <= n;i++){
if (s[i].l > 1){
int l = lower_bound(p.begin(),p.end(),s[i].l) - p.begin() + 1;
int r = lower_bound(p.begin(),p.end(),s[i].r + 1) - p.begin() + 1;
arr[l]++;
arr[r]--;
}
}
for (re int i = 1;i <= 2 * n;i++){
arr[i] += arr[i - 1];
ans = max(ans,arr[i]);
}
for (re int i = 1;i <= 2 * n;i++) arr[i] = 0;
for (re int i = 1;i <= n;i++){
if (s[i].r < m){
int l = lower_bound(p.begin(),p.end(),s[i].l) - p.begin() + 1;
int r = lower_bound(p.begin(),p.end(),s[i].r + 1) - p.begin() + 1;
arr[l]++;
arr[r]--;
}
}
for (re int i = 1;i <= 2 * n;i++){
arr[i] += arr[i - 1];
ans = max(ans,arr[i]);
}
printf("%d\n",ans);
}
int main(){
T = read();
while (T--) solve();
return 0;
}

浙公网安备 33010602011771号