三十年河东,三十年河西|

自动机

园龄:1年10个月粉丝:2关注:4

Codeforces Round 892 (Div. 2)

C:

题意:

找出一个n的全排列使得(i=1i=npii) - (maxj=1j=npjj) 最大

思路:

因为想让大的数字不被浪费掉,所以就把它和次小的数反转一下 ==> 选一段后缀反转暴力枚举一下

inline void solve() 
{
    int n; cin >> n;
    LL ans = -INF;
    for (int i = 1; i <= n; i++)
    {
        LL sum = 0, maxx = -INF;
        for (int j = 1; j < i; j++)
        {
            sum += j * j;
            maxx = max((LL)(j * j), maxx);
        }
        for (int j = i; j <= n; j++)
        {
            sum += j * (n - (j - i));
            maxx = max((LL)(j * (n - (j - i))), maxx);
        }
        ans = max(ans, sum - maxx);
    }
    cout << ans << endl;
}

D:

题意:

给你只包含四个数的元组[l, r, a, b] 对于区间[l, r]而言区间[a, b]一定是它的子区间,如果当前你位于区间[l, r]之间,那么你可以使用传送门到达[a, b]的任意点,给你q个询问每次给你一个初始位置问你最远可以到哪

思路:

因为我们只能使用传送门行动所以[l, r, a, b]对我们来说只有[l, b]是有用的,所以先把所有的[l, b]区间合并,然后对每个查询查找一下这个数位在哪个区间里面,那它最远就是到这个区间的右端点

inline void solve() 
{
    int n; cin >> n;
    std::vector<std::array<int, 2>> seg(n);
    for (int i = 0; i < n; i++)
    {
        int l, a, b ,r; cin >> l >> r >> a >> b;
        seg.push_back({l, b});
    }

    sort(seg.begin(), seg.end());
    vector<array<int, 2>> a;

    for (auto [l, r] : seg)
    {
        if (!a.empty() && l <= a.back()[1])
        {
            a.back()[1] = max(r, a.back()[1]);
        }
        else
        {
            a.push_back({l, r});
        }
    }

    int q; cin >> q;
    while (q--)
    {
        int x; cin >> x;
        int l = 0, r = a.size() - 1;
        while (l < r)
        {
            int mid = (l + r + 1) / 2;
            if (x >= a[mid][0]) l = mid;
            else r = mid - 1;
        }

        if (x >= a[l][0])
        {
            cout << max(x, a[l][1]) << " \n"[q == 0];
        }
        else cout << x << " \n"[q == 0];

    }
}

本文作者:自动机

本文链接:https://www.cnblogs.com/monituihuo/articles/17626882.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   自动机  阅读(4)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起