[题解]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;  
}  
posted @ 2024-06-25 12:29  WBIKPS  阅读(25)  评论(0)    收藏  举报