Submission #1130498

#TimeUsernameProblemLanguageResultExecution timeMemory
1130498joelgun14Joker (BOI20_joker)C++20
0 / 100
103 ms5408 KiB
#include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> #pragma GCC optimize("Ofast") #pragma GCC optimize("unroll-loops") #define endl "\n" #define ll long long #define mp make_pair #define ins insert #define lb lower_bound #define pb push_back #define ub upper_bound #define lll __int128 #define fi first #define se second using namespace std; using namespace __gnu_pbds; typedef tree<int, null_type, less_equal<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_multiset; typedef tree<int, null_type, less<int>, rb_tree_tag,tree_order_statistics_node_update> ordered_set; const int lim = 2e5 + 5; struct disjoint_set { int h[lim], sz[lim]; bool par[lim], cycle[lim]; int cnt = 0; // x, y vector<pair<int, int>> rb; disjoint_set() { memset(h, -1, sizeof(h)); fill(sz, sz + lim, 1); memset(par, 0, sizeof(par)); memset(cycle, 0, sizeof(cycle)); } int fh(int nd) { return h[nd] == -1 ? nd : fh(h[nd]); } bool get_par(int nd) { return h[nd] == -1 ? par[nd] : par[nd] ^ get_par(h[nd]); } void merge(int x, int y) { int xh = fh(x), yh = fh(y); if(xh != yh) { if(sz[xh] < sz[yh]) swap(xh, yh); if(get_par(x) == get_par(y)) par[yh] = 1; h[yh] = xh; sz[xh] += sz[yh]; rb.pb(mp(xh, yh)); } else { if(get_par(x) == get_par(y)) { // cerr << "THIS HAPPENED" << endl; // cerr << x << " " << y << endl; cycle[xh] = 1; rb.pb(mp(xh, xh)); ++cnt; } else { rb.pb(mp(-1, -1)); } } } void merge(pair<int, int> a) { merge(a.fi, a.se); } void rollback() { if(rb.size()) { if(rb.back() != mp(-1, -1)) { pair<int, int> cur = rb.back(); if(cur.fi == cur.se) { --cnt; cycle[cur.fi] = 0; } else { h[cur.se] = -1; sz[cur.fi] -= sz[cur.se]; par[cur.se] = 0; } } rb.pop_back(); } } void clear() { while(rb.size()) rollback(); } } dsu; const int lim2 = 1 << 4; int ans[lim]; pair<int, int> adj[lim]; struct segtree { int cur_right; segtree() { } void query(int nd, int cl, int cr, int l, int r) { if(cl > r || cr < l) return; // cerr << "QUERY" << endl; if(cl == cr) { // one point only dsu.merge(adj[cl]); int ocr = cur_right; while(cur_right > 1) { --cur_right; dsu.merge(adj[cur_right]); if(dsu.cnt > 0) { ++cur_right; dsu.rollback(); break; } } // if still here it holds true, then the answer is just infinity if(dsu.cnt > 0) ans[cl] = lim2; else ans[cl] = cur_right; while(cur_right < ocr) ++cur_right, dsu.rollback(); } else { // check right and check left for(int i = cl; i <= cr; ++i) dsu.merge(adj[cur_right]); int ocr = cur_right; while(cur_right > 1) { --cur_right; dsu.merge(adj[cur_right]); if(dsu.cnt > 0) { ++cur_right; dsu.rollback(); break; } } for(int i = 0; i < ocr - cur_right; ++i) dsu.rollback(); for(int i = cl; i <= cr; ++i) dsu.rollback(); int ncr = cur_right; cur_right = ocr; while(cur_right > ncr) { --cur_right; dsu.merge(adj[cur_right]); } // insert all lc int mid = (cl + cr) >> 1; for(int i = cl; i <= mid; ++i) dsu.merge(adj[i]); query((nd << 1) | 1, mid + 1, cr, l, r); for(int i = cl; i <= mid; ++i) dsu.rollback(); query((nd << 1), cl, mid, l, r); while(cur_right < ocr) dsu.rollback(), ++cur_right; } // cerr << "DONE" << endl; } } seg; int main() { ios_base::sync_with_stdio(0); cin.tie(NULL); int n, m, q; cin >> n >> m >> q; adj[0] = mp(0, lim - 1); for(int i = 1; i <= m; ++i) { cin >> adj[i].fi >> adj[i].se; } seg.cur_right = m + 1; seg.query(1, 0, lim2 - 1, 0, m - 1); // for(int i = 0; i < m; ++i) // cerr << ans[i] << " "; // cerr << endl; for(int i = 0; i < q; ++i) { int x, y; cin >> x >> y; if(ans[x - 1] - 1 > y) cout << "YES" << endl; else cout << "NO" << endl; } 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...