Submission #389105

#TimeUsernameProblemLanguageResultExecution timeMemory
389105arujbansalJoker (BOI20_joker)C++17
0 / 100
80 ms14132 KiB
#include <iostream> #include <algorithm> #include <vector> #include <map> #include <set> #include <array> #include <stack> #include <queue> #include <random> #include <numeric> #include <functional> #include <chrono> #include <utility> #include <iomanip> #include <assert.h> using namespace std; void dbg_out() { cerr << endl; } template<typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cerr << ' ' << H; dbg_out(T...); } #define dbg(...) cerr << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__) #define rng_init mt19937 rng(chrono::steady_clock::now().time_since_epoch().count()) #define rng_seed(x) mt19937 rng(x) #define all(x) (x).begin(), (x).end() #define sz(x) (int) (x).size() // #define int long long const int MXN = 2e5 + 5, INF = 1e9 + 5; int N, M, Q; pair<int, int> edges[MXN]; int info[MXN], parity[MXN]; int is_bipartite; stack<array<int, 4>> changes; // {node, size of component, did this make the graph non bipartite} int valid[MXN]; pair<int, int> find_par(int x) { if (info[x] < 0) return make_pair(x, parity[x]); pair<int, int> p = find_par(info[x]); p.second ^= 1; return p; } void unite(int x, int y) { auto [px, parity_x] = find_par(x); auto [py, parity_y] = find_par(y); if (px == py) { if (parity_x == parity_y) { changes.emplace(array<int, 4>{py, -info[py], is_bipartite, parity[py]}); is_bipartite = 0; } else { changes.emplace(array<int, 4>{py, -info[py], 0, parity[py]}); } return; } if (info[px] > info[py]) { swap(px, py); swap(parity_x, parity_y); swap(x, y); } changes.emplace(array<int, 4>{py, -info[py], 0, parity[py]}); parity[py] = parity_x ^ parity_y ^ 1; info[px] += info[py]; info[py] = px; } void rollback() { assert(changes.empty() == false); auto [y, comp_sz, non_bipartite, parity_y] = changes.top(); int x = info[y]; if (x == y) return; parity[y] = parity_y; info[x] += comp_sz; info[y] = -comp_sz; if (non_bipartite) is_bipartite = 1; changes.pop(); } void add_edge(int idx) { unite(edges[idx].first, edges[idx].second); } void dnc(int l, int r, int optl, int optr) { if (l > r) return; int mid = (l + r) / 2; // dbg(l, r, mid); // dbg(optl, optr); // Add prefix of edges for (int i = max(0, l - 1); i < mid; i++) add_edge(i); // dbg(sz(changes)); int ufds_r = optr; // Edge list pointer // Calculate optimal right for mid, store in best int best = 0; while (ufds_r > mid + 1 && ufds_r >= optl && is_bipartite) add_edge(--ufds_r); // dbg(ufds_r, sz(changes)); if (!is_bipartite) best = ufds_r; valid[mid] = best; // dbg(is_bipartite, best); // Right side will be dnc(mid + 1, r, best, optr) // For right side, already have prefix, need to work on removing suffix while (ufds_r < optr) { rollback(); ufds_r++; } // dbg(ufds_r, sz(changes)); // dbg(is_bipartite, best); // dbg_out(); // if (mid == 1) { // for (int i = 0; i < N; i++) { // find_par(i); // dbg(i, parity[i]); // } // exit(0); // } dnc(mid + 1, r, best, optr); // Remove prefix for (int i = mid - 1; i >= max(0, l - 1); i--) rollback(); // Now add those edges again while (ufds_r > best + 1) add_edge(--ufds_r); // Left side will be dnc(l, mid - 1, optl, best + 1) dnc(l, mid - 1, optl, best + 1); // Rollback suffix add while (ufds_r < optr) { rollback(); ufds_r++; } } void solve() { cin >> N >> M >> Q; for (int i = 0; i < M; i++) { cin >> edges[i].first >> edges[i].second; edges[i].first--, edges[i].second--; } is_bipartite = 1; for (int i = 0; i < MXN; i++) info[i] = -1, parity[i] = 0; dnc(0, M - 1, 0, M); // for (int i = 0; i < M; i++) // dbg(i, valid[i]); while (Q--) { int l, r; cin >> l >> r; l--, r--; cout << (valid[l] > r ? "YES" : "NO") << "\n"; } } signed main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); int TC = 1; // cin >> TC; while (TC--) solve(); }
#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...