QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#607925#9424. Stop the Castle 2ucup-team4435#RE 1ms3596kbC++208.5kb2024-10-03 17:08:232024-10-03 17:08:23

Judging History

This is the latest submission verdict.

  • [2024-10-03 17:08:23]
  • Judged
  • Verdict: RE
  • Time: 1ms
  • Memory: 3596kb
  • [2024-10-03 17:08:23]
  • Submitted

answer

#pragma GCC optimize("Ofast")

#include "bits/stdc++.h"

#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rep1(i, n) for (int i = 1; i < (n); ++i)
#define rep1n(i, n) for (int i = 1; i <= (n); ++i)
#define repr(i, n) for (int i = (n) - 1; i >= 0; --i)
#define pb push_back
#define eb emplace_back
#define all(a) (a).begin(), (a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define each(x, a) for (auto &x : a)
#define ar array
#define vec vector
#define range(i, n) rep(i, n)

using namespace std;

using ll = long long;
using ull = unsigned long long;
using ld = long double;
using str = string;
using pi = pair<int, int>;
using pl = pair<ll, ll>;

using vi = vector<int>;
using vl = vector<ll>;
using vpi = vector<pair<int, int>>;
using vvi = vector<vi>;

int Bit(int mask, int b) { return (mask >> b) & 1; }

template<class T>
bool ckmin(T &a, const T &b) {
    if (b < a) {
        a = b;
        return true;
    }
    return false;
}

template<class T>
bool ckmax(T &a, const T &b) {
    if (b > a) {
        a = b;
        return true;
    }
    return false;
}

// [l, r)
template<typename T, typename F>
T FindFirstTrue(T l, T r, const F &predicat) {
    --l;
    while (r - l > 1) {
        T mid = l + (r - l) / 2;
        if (predicat(mid)) {
            r = mid;
        } else {
            l = mid;
        }
    }
    return r;
}


template<typename T, typename F>
T FindLastFalse(T l, T r, const F &predicat) {
    return FindFirstTrue(l, r, predicat) - 1;
}


const ll INF = 2e18;
const int INFi = 1e9;
const int N = 30 + 5;
const int LG = 20;

struct matching {
    int n, m;
    std::vector<std::vector<int>> g;
    std::vector<int> p_left, p_right;

    matching(int n = 0, int m = 0) :
            n(n), m(m), g(n), p_left(n, -1), p_right(m, -1)
    {}

    std::pair<int, int> size() const {
        return {n, m};
    }

    void add(int left, int right) {
        g[left].push_back(right);
    }

    std::vector<int> used;
    int pairs = 0;

    bool khun(int v) {
        if (used[v] == pairs + 1)
            return false;

        used[v] = pairs + 1;
        for (auto u : g[v])
            if (p_right[u] == -1) {
                p_right[u] = v;
                p_left[v] = u;
                return true;
            }

        for (auto u : g[v])
            if (khun(p_right[u])) {
                p_right[u] = v;
                p_left[v] = u;
                return true;
            }

        return false;
    }

    int solve(bool need_to_shuffle = false) {
        std::fill(p_left.begin(), p_left.end(), -1);
        std::fill(p_right.begin(), p_right.end(), -1);
        used.assign(n, 0);

        std::vector<int> order(n);
        std::iota(order.begin(), order.end(), 0);
        if (need_to_shuffle) {
            std::shuffle(order.begin(), order.end(), std::mt19937(std::chrono::steady_clock::now().time_since_epoch().count()));
            for (auto &v : g)
                std::shuffle(v.begin(), v.end(), std::mt19937(std::chrono::steady_clock::now().time_since_epoch().count()));
        }

        pairs = 0;
        for (int v : order)
            pairs += khun(v);

        return pairs;
    }

    void dfs(int v) {
        if (used[v])
            return;

        used[v] = 1;
        for (auto u : g[v])
            if (u != p_left[v])
                dfs(p_right[u]);
    }

    std::pair<std::vector<int>, std::vector<int>> minimum_vertex_covering(bool need_to_shuffle = false) {
        int pairs = solve(need_to_shuffle);
        used.assign(n, 0);

        for (int i = 0; i < n; i++)
            if (p_left[i] == -1)
                dfs(i);

        std::vector<int> left;
        std::vector<bool> used_right(m);

        for (int i = 0; i < n; i++)
            if (!used[i]) {
                left.push_back(i);
            } else if (p_left[i] != -1) {
                for (auto j : g[i])
                    used_right[j] = true;
            }

        std::vector<int> right;
        for (int i = 0; i < m; i++)
            if (used_right[i])
                right.push_back(i);

        assert(int(left.size() + right.size()) == pairs);
        return std::make_pair(left, right);
    }
};


void solve() {
    int n, m, k; cin >> n >> m >> k;
    vpi a(n), b(m);
    rep(i, n) cin >> a[i].first >> a[i].second;
    rep(i, m) cin >> b[i].first >> b[i].second;
    vi xx, yy;
    rep(i, n) {
        xx.push_back(a[i].first);
        yy.push_back(a[i].second);
    }
    rep(i, m) {
        xx.push_back(b[i].first);
        yy.push_back(b[i].second);
    }
    sort(all(xx));
    xx.resize(unique(all(xx)) - xx.begin());
    sort(all(yy));
    yy.resize(unique(all(yy)) - yy.begin());
    rep(i, n) {
        a[i].first = lower_bound(all(xx), a[i].first) - xx.begin();
        a[i].second = lower_bound(all(yy), a[i].second) - yy.begin();
    }
    rep(i, m) {
        b[i].first = lower_bound(all(xx), b[i].first) - xx.begin();
        b[i].second = lower_bound(all(yy), b[i].second) - yy.begin();
    }
    int szx = xx.size();
    int szy = yy.size();
    vector<vector<ar<int, 3>>> in_row(szx), in_col(szy);
    rep(i, n) {
        in_row[a[i].first].push_back({a[i].second, 0, i});
        in_col[a[i].second].push_back({a[i].first, 0, i});
    }
    rep(i, m) {
        in_row[b[i].first].push_back({b[i].second, 1, i});
        in_col[b[i].second].push_back({b[i].first, 1, i});
    }
    vector<pair<int, int>> to(m, {-1, -1});
    int ans = 0;
    int L = 0;
    int R = 0;
    vector<pair<int, int>> edges;
    rep(i, szx) {
        vector<ar<int, 3>> &cur = in_row[i];
        sort(all(cur));
        for(int l = 0, r = 0; l < cur.size(); l = r) {
            r = l + 1;
            if (cur[l][1]) continue;
            while (r < cur.size() && cur[r][1]) r++;
            if (r == cur.size()) {
                continue;
            }
            if (r == l + 1) {
                ans++;
                continue;
            }
            ans++;
            int v = L++;
            for(int j = l + 1; j < r; ++j) {
                to[cur[j][2]].first = v;
            }
        }
    }
    rep(i, szy) {
        vector<ar<int, 3>> &cur = in_col[i];
        sort(all(cur));
        for(int l = 0, r = 0; l < cur.size(); l = r) {
            r = l + 1;
            if (cur[l][1]) continue;
            while (r < cur.size() && cur[r][1]) r++;
            if (r == cur.size()) {
                continue;
            }
            if (r == l + 1) {
                ans++;
                continue;
            }
            ans++;
            int v = R++;
            for(int j = l + 1; j < r; ++j) {
                to[cur[j][2]].second = v;
            }
        }
    }
    vector<int> ok(m, 0);
    vector<vi> gL(L), gR(R);
    matching g(L, R);
    map<pair<int, int>, int> edge;
    rep(i, m) {
        if (to[i].first == -1 && to[i].second == -1) {
            continue;
        }
        if (to[i].first == -1) {
            gR[to[i].second].push_back(i);
            continue;
        }
        if (to[i].second == -1) {
            gL[to[i].first].push_back(i);
            continue;
        }
        gL[to[i].first].push_back(i);
        gR[to[i].second].push_back(i);
        g.add(to[i].first, to[i].second);
        edge[to[i]] = i;
    }

    int l = m - k;
    int cnt2 = g.solve();
    rep(i, L) {
        if (g.p_left[i] != -1 && l > 0) {
            ans -= 2;
            pair<int, int> e = {i, g.p_left[i]};
            int ind = edge.at(e);
            ok[ind] = 1;
            l--;
            continue;
        }
    }
    rep(i, L) {
        if (g.p_left[i] == -1 && l > 0) {
            for(auto &j : gL[i]) {
                ans--;
                ok[j] = 1;
                break;
            }
        }
    }
    rep(i, R) {
        if (g.p_right[i] == -1 && l > 0) {
            for(auto &j : gR[i]) {
                ans--;
                ok[j] = 1;
                break;
            }
        }
    }
    rep(i, m) {
        if (l > 0 && !ok[i]) {
            ok[i] = 1;
            l--;
        }
    }
    assert(l == 0);
    cout << ans << '\n';
    rep(i, m) if (!ok[i]) cout << i + 1 << ' ';
    cout << '\n';
}


signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout << setprecision(12) << fixed;
    int t = 1;
    cin >> t;
    rep(i, t) {
        solve();
    }
    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 1ms
memory: 3596kb

input:

3
8 6 4
1 3
2 1
2 6
4 1
4 7
6 1
6 3
6 6
2 3
3 1
4 3
4 6
5 2
6 4
3 2 1
10 12
10 10
10 11
1 4
1 5
1 3 2
1 1
2 1
2 2
2 3

output:

4
2 3 5 6 
2
2 
0
2 3 

result:

ok ok 3 cases (3 test cases)

Test #2:

score: -100
Runtime Error

input:

1224
11 17 14
7 3
4 2
8 13
3 15
3 4
5 11
10 2
3 3
8 6
7 11
2 3
10 4
1 3
12 1
2 5
11 9
11 6
11 10
8 15
1 5
9 14
4 11
1 6
10 7
7 6
11 4
8 4
1 11
18 3 2
14 8
2 14
13 13
9 12
14 12
5 6
8 1
10 5
8 6
8 9
6 6
7 5
12 11
6 11
13 5
1 10
7 6
14 5
6 15
2 4
11 1
1 6 4
14 14
13 9
9 3
10 12
7 5
8 13
9 14
1 9 8
4 9...

output:


result: