Cutting Game

大家好,我是 STL 带师。

按行和列维护两个 map 套 set。

剪掉某个部分时,在对应 map 中二分出要删除的区间。遍历即将删除的内容,在另一个 map 中同步删除。

#include <bits/extc++.h>
using namespace std;
namespace pbds = __gnu_pbds;
using ui = unsigned int;
using uli = unsigned long long int;
using li = long long int;
int main(void) {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    size_t T;
    cin >> T;
    while (T--) {
        ui xh, yh, xl = 1, yl = 1;
        size_t n, m;
        cin >> xh >> yh >> n >> m;
        map<ui, set<ui>> xp, yp;
        while (n--) {
            size_t x, y;
            cin >> x >> y;
            xp[x].emplace(y), yp[y].emplace(x);
        }
        ui sum1 = 0, sum2 = 0;
        for (bool b = 1; m; b = !b, --m) {
            char c;
            ui k;
            cin >> c >> k;
            ui ans = 0;
            if (c == 'D')
                for (auto it = xp.upper_bound(xh -= k); it != xp.end(); it = xp.erase(it))
                    for (auto j : it->second)
                        yp[j].erase(it->first), ++ans;
            else if (c == 'U') {
                auto et = xp.lower_bound(xl += k);
                for (auto it = xp.begin(); it != et; it = xp.erase(it))
                    for (auto j : it->second)
                        yp[j].erase(it->first), ++ans;
            } else if (c == 'R')
                for (auto it = yp.upper_bound(yh -= k); it != yp.end(); it = yp.erase(it))
                    for (auto j : it->second)
                        xp[j].erase(it->first), ++ans;
            else if (c == 'L') {
                auto et = yp.lower_bound(yl += k);
                for (auto it = yp.begin(); it != et; it = yp.erase(it))
                    for (auto j : it->second)
                        xp[j].erase(it->first), ++ans;
            }
            (b ? sum1 : sum2) += ans;
        }
        cout << sum1 << ' ' << sum2 << '\n';
    }
    return 0;
}
posted @ 2024-05-21 07:56  MrPython  阅读(5)  评论(0)    收藏  举报  来源