QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#160623#7105. Pixel Artucup-team1469#WA 1ms3664kbC++176.9kb2023-09-02 20:59:232023-09-02 20:59:24

Judging History

你现在查看的是最新测评结果

  • [2023-09-02 20:59:24]
  • 评测
  • 测评结果:WA
  • 用时:1ms
  • 内存:3664kb
  • [2023-09-02 20:59:23]
  • 提交

answer

#ifndef LOCAL
#define FAST_IO
#endif

// ============
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#define OVERRIDE(a, b, c, d, ...) d
#define REP2(i, n) for (i32 i = 0; i < (i32)(n); ++i)
#define REP3(i, m, n) for (i32 i = (i32)(m); i < (i32)(n); ++i)
#define REP(...) OVERRIDE(__VA_ARGS__, REP3, REP2)(__VA_ARGS__)
#define PER(i, n) for (i32 i = (i32)(n) - 1; i >= 0; --i)
#define ALL(x) begin(x), end(x)

using namespace std;

using u32 = unsigned int;
using u64 = unsigned long long;
using i32 = signed int;
using i64 = signed long long;
using f64 = double;
using f80 = long double;

template <typename T>
using Vec = vector<T>;

template <typename T>
bool chmin(T &x, const T &y) {
    if (x > y) {
        x = y;
        return true;
    }
    return false;
}
template <typename T>
bool chmax(T &x, const T &y) {
    if (x < y) {
        x = y;
        return true;
    }
    return false;
}

#ifdef INT128

using u128 = __uint128_t;
using i128 = __int128_t;

istream &operator>>(istream &is, i128 &x) {
    i64 v;
    is >> v;
    x = v;
    return is;
}
ostream &operator<<(ostream &os, i128 x) {
    os << (i64)x;
    return os;
}
istream &operator>>(istream &is, u128 &x) {
    u64 v;
    is >> v;
    x = v;
    return is;
}
ostream &operator<<(ostream &os, u128 x) {
    os << (u64)x;
    return os;
}

#endif

[[maybe_unused]] constexpr i32 INF = 1000000100;
[[maybe_unused]] constexpr i64 INF64 = 3000000000000000100;
struct SetUpIO {
    SetUpIO() {
#ifdef FAST_IO
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
#endif
        cout << fixed << setprecision(15);
    }
} set_up_io;
// ============

#ifdef DEBUGF
#else
#define DBG(x) (void)0
#endif

// ============

#include <cassert>
#include <utility>
#include <vector>

class UnionFind {
    std::vector<int> par;

    int _root(int v) {
        if (par[v] < 0) {
            return v;
        } else {
            return par[v] = _root(par[v]);
        }
    }

public:
    UnionFind(int n) : par(n, -1) {}

    int root(int v) {
        assert(v >= 0 && v < (int) par.size());
        return _root(v);
    }

    int size(int v) {
        assert(v >= 0 && v < (int) par.size());
        return -par[_root(v)];
    }

    bool unite(int u, int v) {
        assert(u >= 0 && u < (int) par.size() && v >= 0 && v < (int) par.size());
        u = _root(u);
        v = _root(v);
        if (u == v) {
            return false;
        }
        if (par[u] < par[v]) {
            std::swap(u, v);
        }
        par[v] += par[u];
        par[u] = v;
        return true;
    }

    bool same(int u, int v) {
        assert(u >= 0 && u < (int) par.size() && v >= 0 && v < (int) par.size());
        return _root(u) == _root(v);
    }
};

// ============

void solve() {
    i32 n, m, k;
    cin >> n >> m >> k;
    Vec<tuple<i32, i32, i32, i32>> lines(k);
    for (auto &[a, b, c, d] : lines) {
        cin >> a >> b >> c >> d;
        --a;
        --b;
        --c;
        --d;
    }
    Vec<Vec<pair<i32, i32>>> vert(n);
    Vec<Vec<pair<i32, i32>>> horz(m);
    for (auto [a, b, c, d] : lines) {
        if (a == c) {
            horz[a].emplace_back(b, d + 1);
        } else {
            vert[a].emplace_back(b, c + 1);
        }
    }
    Vec<pair<i32, i32>> pts;
    const i32 dx[] = {1, 0, -1, 0, 0}, dy[] = {0, 1, 0, -1, 0};
    for (auto [a, b, c, d] : lines) {
        REP(dir, 5) {
            i32 x = a + dx[dir], y = b + dy[dir];
            if (0 <= x && x < n && 0 <= y && y < m) {
                pts.emplace_back(x, y);
            }
            x = c + dx[dir], y = d + dy[dir];
            if (0 <= x && x < n && 0 <= y && y < m) {
                pts.emplace_back(x, y);
            }
        }
    }
    sort(ALL(pts));
    pts.erase(unique(ALL(pts)), pts.end());
    Vec<Vec<pair<i32, i32>>> yoko(n), tate(m);
    REP(i, pts.size()) {
        yoko[pts[i].first].push_back(pts[i]);
        tate[pts[i].second].push_back(pts[i]);
    }
    REP(i, m) {
        sort(ALL(tate[i]));
    }
    UnionFind uf(pts.size());
    Vec<i32> add(n + 2, 0);
    REP(i, n) {
        for (auto [l, r] : horz[i]) {
            add[i] += r - l;
            add[i + 1] -= r - l;
        }
        for (auto [a, b] : vert[i]) {
            add[i] += 1;
            add[b] -= 1;
        }
    }
    REP(i, n) {
        add[i + 1] += add[i];
    }
    Vec<i32> alive(pts.size(), 0);
    i32 comp = 0;
    const auto create = [&](i32 x) -> void {
        if (!alive[x]) {
            ++comp;
            alive[x] = 1;
        }
    };
    const auto unite = [&](i32 x, i32 y) -> void {
        if (uf.unite(x, y)) {
            --comp;
        }
    };
    const auto idx = [&](pair<i32, i32> x) -> i32 {
        return lower_bound(ALL(pts), x) - pts.begin();
    };
    REP(i, n) {
        for (auto [l, r] : horz[i]) {
            auto it = lower_bound(ALL(yoko[i]), make_pair(i, l));
            i32 prv = -1;
            while (it != yoko[i].end() && it->second < r) {
                i32 j = idx(*it);
                create(j);
                if (prv != -1) {
                    unite(prv, j);
                }
                REP(dir, 4) {
                    pair<i32, i32> pt(it->first + dx[dir], it->second + dy[dir]);
                    if (binary_search(ALL(pts), pt)) {
                        i32 k = idx(pt);
                        if (alive[k]) {
                            unite(j, k);
                        }
                    }
                }
                prv = j;
                ++it;
            }
        }
        for (auto [y, to] : vert[i]) {
            auto it = lower_bound(ALL(tate[y]), make_pair(i, y));
            i32 prv = -1;
            while (it != tate[y].end() && it->first < to) {
                i32 j = idx(*it);
                create(j);
                if (prv != -1) {
                    unite(prv, j);
                }
                REP(dir, 4) {
                    pair<i32, i32> pt(it->first + dx[dir], it->second + dy[dir]);
                    if (binary_search(ALL(pts), pt)) {
                        i32 k = idx(pt);
                        if (alive[k]) {
                            unite(j, k);
                        }
                    }
                }
                prv = j;
                ++it;
            }
        }
        cout << add[i] << ' ' << comp << '\n';
    }
}

int main() {
    i32 t;
    cin >> t;
    while (t--) {
        solve();
    }
}

详细

Test #1:

score: 0
Wrong Answer
time: 1ms
memory: 3664kb

input:

3
2 5 2
1 1 1 2
2 3 2 5
2 5 2
1 1 1 3
2 3 2 5
3 3 3
1 1 1 2
3 1 3 2
1 3 2 3

output:

2 1
3 2
3 1
3 1
3 1
1 1
2 2

result:

wrong answer 2nd lines differ - expected: '5 2', found: '3 2'