Codeforces Round 904 (Div. 2) C. Medium Design

jly:开始的想法:首先枚举max的位置。包含它的一定是全加,剩下的一定都不加。然后求所有位置的最小值。
初始全0,枚举max之后,因为是加区间,min一定在两端(最左或最右)。所以不需要枚举max,我们枚举min就好(因为加区间和初始全0,这个题的特殊性)。min只能在两端。

令 x 为最佳答案中数组 𝑎 中最大元素的位置。 在这种情况下,我们可以选择 𝑙≤𝑥≤𝑟 的所有线段,因为如果最小元素的位置在该线段之外,我们将答案增加 +1,如果在内部,我们不会使答案变得更糟。 由此可见,最小值要么出现在位置 1,要么出现在位置 m。
写法注意的点:下标从0开始,区间的左端点都-1,右端点不变,记作区间右端点右边那个位置,这样在那个位置-1就合理了。所以枚举min,首先认为min在最左边,那么f中不存左节点为0的点,因为这样的区间其实对最后的答案没有用处,在左节点+1同时也会在max处+1相当于没用。接着模拟过一遍剩下的区间。然后认为min在最右边,重新做一遍这个过程,区别就是f中不存右节点为m的点。

#include <cstdio>
#include <vector>
#include <queue>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <stack>

using namespace std;
typedef long long ll;
typedef pair<int, int>P;
const int maxn = 1e5 + 10;
const int INF = 0x3f3f3f3f;
const ll mod = 998244353;
const double eps = 1e-11;
const double pi = 3.141592653;

void solve()
{
    int n, m;
    cin >> n >> m;
    vector<int> l(n), r(n);
    for(int i = 0; i < n; ++i)
    {
        cin >> l[i] >> r[i];
        l[i] -= 1;
    }

    //首先枚举最小值在最左边
    vector<P> f;
    for(int i = 0; i < n; ++i)
    {
        if(l[i] != 0)
        {
            f.emplace_back(l[i], 1);
            f.emplace_back(r[i], -1);
        }
    }
    int ans = 0;
    int cur = 0, lst = 0;
    sort(f.begin(), f.end());
    for(auto [x,y] : f)
    {
        //cout << "(" << x << ", " << y << ") " << cur << " ";
        if(x > lst)
        {
            ans = max(ans, cur);
        }
        cur += y;
        lst = x;
    }
    if(m > lst) ans = max(ans, cur);

    //然后枚举最小值在最右边
    f.clear();
    for(int i = 0; i < n; ++i)
    {
        if(r[i] != m)
        {
            f.emplace_back(l[i], 1);
            f.emplace_back(r[i], -1);
        }
    }
    //cout << endl;
    cur = 0, lst = 0;
    sort(f.begin(), f.end());
    for(auto [x,y] : f)
    {
        //cout << "(" << x << ", " << y << ") " << cur << " ";
        if(x > lst)
        {
            ans = max(ans, cur);
        }
        cur += y;
        lst = x;
    }
    if(m > lst) ans = max(ans, cur);
    cout << ans << "\n";
}

int main()
{
    int t;
    cin >> t;
    while(t--)
    {
        solve();
    }
    return 0;
}
posted @ 2023-12-03 17:40  .Ivorelectra  阅读(12)  评论(0编辑  收藏  举报