Submission #261668

#TimeUsernameProblemLanguageResultExecution timeMemory
261668rama_pangJoker (BOI20_joker)C++14
100 / 100
472 ms18132 KiB
#include <bits/stdc++.h> using namespace std; const int MAXN = 200005; int N, M, Q; pair<int, int> edges[MAXN]; // Disjoint Set with rollbacks int par[MAXN * 2]; int sz[MAXN * 2]; vector<pair<int, int>> hist; int Find(int x) { return par[x] == x ? x : Find(par[x]); } int Unite(int x, int y) { x = Find(x), y = Find(y); if (x == y) return 0; if (sz[x] > sz[y]) swap(x, y); hist.emplace_back(x, par[x]); hist.emplace_back(y, sz[y]); par[x] = y; sz[y] += sz[x]; return 1; } void Rollback(int x) { while (x--) { sz[hist.back().first] = hist.back().second; hist.pop_back(); par[hist.back().first] = hist.back().second; hist.pop_back(); } } int last[MAXN]; // last[L] = highest R, such that erasing edges = [L...R), odd cycle still exist void FindOpt(int ll, int lr, int rl, int rr) { if (ll > lr) return; int l = (ll + lr) / 2; int r = rr; int ops = 0; int odd_cycle = 0; for (int i = ll; i < l; i++) { ops += Unite(edges[i].first + MAXN, edges[i].second); ops += Unite(edges[i].first, edges[i].second + MAXN); if (Find(edges[i].first) == Find(edges[i].first + MAXN)) { odd_cycle = 1; Rollback(ops); ops = 0; last[l] = r = M + 1; break; } } for (int i = rr; odd_cycle == 0 && i >= max(l, rl); i--) { ops += Unite(edges[i].first + MAXN, edges[i].second); ops += Unite(edges[i].first, edges[i].second + MAXN); if (Find(edges[i].first) == Find(edges[i].first + MAXN)) { last[l] = r = i; Rollback(ops); ops = 0; break; } } odd_cycle = 0; for (int i = r + 1; i <= rr; i++) { ops += Unite(edges[i].first + MAXN, edges[i].second); ops += Unite(edges[i].first, edges[i].second + MAXN); if (Find(edges[i].first) == Find(edges[i].first + MAXN)) { odd_cycle = 1; Rollback(ops); ops = 0; for (int j = ll; j < l; j++) { last[j] = M + 1; } break; } } if (odd_cycle == 0) { FindOpt(ll, l - 1, rl, r); Rollback(ops); ops = 0; } odd_cycle = 0; for (int i = ll; i <= l; i++) { ops += Unite(edges[i].first + MAXN, edges[i].second); ops += Unite(edges[i].first, edges[i].second + MAXN); if (Find(edges[i].first) == Find(edges[i].first + MAXN)) { odd_cycle = 1; Rollback(ops); ops = 0; for (int j = l + 1; j <= lr; j++) { last[j] = M + 1; } break; } } if (odd_cycle == 0) { FindOpt(l + 1, lr, r, rr); Rollback(ops); ops = 0; } } int main() { ios::sync_with_stdio(0); cin.tie(0), cout.tie(0); iota(par, par + MAXN * 2, 0); fill(sz, sz + MAXN * 2, 1); cin >> N >> M >> Q; for (int i = 1; i <= M; i++) { cin >> edges[i].first >> edges[i].second; } edges[M + 1].first = N + 1, edges[M + 1].second = N + 2; FindOpt(1, M, 1, M + 1); for (int i = 1; i <= Q; i++) { int l, r; cin >> l >> r; if (r < last[l]) { cout << "YES\n"; } else { cout << "NO\n"; } } return 0; }
#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...