ABC 186

https://atcoder.jp/contests/abc186

A. Brick

https://atcoder.jp/contests/abc186/tasks/abc186_a

B. Blocks on Grid

https://atcoder.jp/contests/abc186/tasks/abc186_b

C. Unlucky 7

https://atcoder.jp/contests/abc186/tasks/abc186_c

D. Sum of difference

https://atcoder.jp/contests/abc186/tasks/abc186_d

E. Throne

https://atcoder.jp/contests/abc186/tasks/abc186_e

F. Rook on Grid

https://atcoder.jp/contests/abc186/tasks/abc186_f

2026/2/16 segment tree の問題だとわかった状態で自力 AC

https://kenkoooo.com/atcoder/#/contest/show/76c42792-10db-491b-9486-ffc7f4f226e1?activeTab=Standings

右に行って下に行くことによって行けるマスの数と、下に行ってから右に行くことによって行けるマスの数を足して、ダブルカウントをしている部分を引いていく。

右に行って下に行くことができるマスをタイプ1、下に行ってから右に行くことができるマスをタイプ2とする。 タイプ1かつタイプ2であるようなマスがダブルカウントされているマスである。 そのようなマスは、そのマスより左に障害物がなく、そのマスより上にも障害物がないマスである。 1行ずつ見ていきながら行にあるマスの列番号に障害物があるかどうかを記録していき、各行にあるダブルカウントしているマスの数を数えればいい。

void solve() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    ll H, W, M;
    cin >> H >> W >> M;

    vvll rows(H), cols(W);
    rep(i, M) {
        ll x, y;
        cin >> x >> y;
        x--, y--;
        rows[x].push_back(y);
        cols[y].push_back(x);
    }

    rep(_, 2) {
        rep(i, H) sort(all(rows[i]));
        swap(H, W);
        swap(cols, rows);
    }

    ll ans = 0;
    rep(_, 2) {
        ll fin = H;
        if (cols[0].size()) {
            fin = cols[0][0];
        }
        rep(ri, fin) {
            if (rows[ri].size())
                ans += rows[ri][0];
            else
                ans += W;
        }

        swap(H, W);
        swap(rows, cols);
    }

    auto op = [](ll a, ll b) -> ll { return a + b; };
    auto e = []() -> ll { return 0; };
    segtree<ll, op, e> seg(W);

    ll fin = H;
    if (cols[0].size()) {
        fin = cols[0][0];
    }

    ll r = W;
    if (rows[0].size()) {
        r = rows[0][0];
    }
    rep(ri, fin) {
        ll right = r;
        if (rows[ri].size()) chmin(right, rows[ri][0]);
        ans -= right - seg.prod(0, right);
        for (ll x : rows[ri]) seg.set(x, 1); // 障害物があるマスを 1 にする
    }

    cout << ans << endl;
}