Submission #973417

#TimeUsernameProblemLanguageResultExecution timeMemory
973417cot7302Joker (BOI20_joker)C++17
0 / 100
2045 ms6448 KiB
#include <bits/stdc++.h> using namespace std; struct disjoint_set { int n; vector<int> _; vector<tuple<int, int, int>> op; vector<bool> not_bipartite; disjoint_set(int n) : n(n), _(2 * n + 2), op(), not_bipartite() {} int root(int x) { while (_[x] > 0) x = _[x]; return x; } void __join(int a, int b) { a = root(a), b = root(b); if (a == b) return; if (_[a] > _[b]) swap(a, b); op.emplace_back(a, b, _[b]); _[a] += _[b]; _[b] = a; } void join(int a, int b) { __join(a, b + n + 1); __join(a + n + 1, b); not_bipartite.emplace_back((root(a) == root(a + n + 1) || root(b) == root(b + n + 1))); } bool is_bipartite() const { return not_bipartite.empty() || !not_bipartite.back(); } void roll_back(int cnta, int cntb) { while (cnta > (int)size(op)) { auto [a, b, sz] = op.back(); _[a] -= sz; _[b] = sz; op.pop_back(); } while (cntb > (int)size(not_bipartite)) not_bipartite.pop_back(); } void roll_back(pair<int, int> x) { roll_back(x.first, x.second); } pair<int, int> snapshot() const { return {(int)size(op), (int)size(not_bipartite)}; } }; pair<int, int> edges[200000]; int ans[200000]; int main() { cin.tie(nullptr)->sync_with_stdio(false); int n, m, q; cin >> n >> m >> q; for (int i = 0; i < m; i++) cin >> edges[i].first >> edges[i].second; disjoint_set dsu(n); for (int i = 0; i < m; i++) dsu.join(edges[i].first, edges[i].second); if (dsu.is_bipartite()) { while (q--) cout << "NO\n"; return 0; } dsu.roll_back(0, 0); auto solve = [&](auto&& f, int l, int r, int ql, int qr) -> void { if (l == r) return; int mid = (l + r) >> 1; auto roll = dsu.snapshot(); for (int i = l; i < mid; i++) dsu.join(edges[i].first, edges[i].second); int opt = qr; while (opt >= max(ql, mid) && dsu.is_bipartite()) { dsu.join(edges[opt].first, edges[opt].second); --opt; } ans[mid] = opt; dsu.roll_back(roll); if (l + 1 == r) return; roll = dsu.snapshot(); for (int i = opt + 1; i <= qr; i++) dsu.join(edges[i].first, edges[i].second); f(f, l, mid, ql, opt); dsu.roll_back(roll); roll = dsu.snapshot(); for (int i = l; i <= mid; i++) dsu.join(edges[i].first, edges[i].second); f(f, mid + 1, r, opt, qr); dsu.roll_back(roll); }; solve(solve, 0, m, 0, m - 1); //for (int i = 0; i < m; i++) cout << ans[i] << " \n"[i == m - 1]; for (int l, r; q--; ) { cin >> l >> r; --l; --r; cout << (r <= ans[l] ? "YES\n" : "NO\n"); } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...