Submission #695053

#TimeUsernameProblemLanguageResultExecution timeMemory
695053null_aweJoker (BOI20_joker)C++14
0 / 100
0 ms212 KiB
#include <iostream> #include <vector> #include <set> #include <queue> using namespace std; #define pii pair<int, int> struct link_cut_tree { int n; set<pii> edges; vector<int> r, p; link_cut_tree(int n) : n(n), r(n, 1), p(n) { for (int i = 0; i < n; ++i) p[i] = i; } int find(int a) { return a == p[a] ? a : p[a] = find(p[a]); } bool same(int a, int b) { return find(a) == find(b); } int sz(int a) { return r[find(a)]; } void link(int a, int b) { a = find(a), b = find(b); if (a == b) return; if (r[a] < r[b]) swap(a, b); p[b] = a, r[a] += r[b]; } void calc() { for (int i = 0; i < n; ++i) r[i] = 1, p[i] = i; for (pii edge : edges) link(edge.first, edge.second); } void add(int a, int b) { // cout << "ADD " << a + 1 << ' ' << b + 1 << '\n'; edges.insert({a, b}); calc(); } void erase(int a, int b) { // cout << "ERASE " << a + 1 << ' ' << b + 1 << '\n'; edges.erase({a, b}); calc(); } }; vector<bool> color; vector<set<int>> adj; vector<int> until; int main() { int n, m, q; cin >> n >> m >> q; vector<pii> edges(m); for (int i = 0; i < m; ++i) cin >> edges[i].first >> edges[i].second; for (int i = 0; i < m; ++i) --edges[i].first, --edges[i].second; color.resize(n), adj.resize(n), until.resize(m); link_cut_tree lct(n); int at = m - 1; while (at >= 0) { pii p = edges[at]; int a = p.first, b = p.second; if (lct.same(a, b)) { if (color[a] == color[b]) break; --at; adj[a].insert(b); adj[b].insert(a); lct.add(a, b); continue; } else { int asz = lct.sz(a), bsz = lct.sz(b); if (asz < bsz) swap(a, b); color[b] = !color[a]; set<int> vis; vis.insert(b); queue<int> q; q.push(b); while (q.size()) { int v = q.front(); q.pop(); for (int u : adj[v]) { if (vis.count(u)) continue; vis.insert(u); color[u] = !color[v]; } } if (asz < bsz) swap(a, b); --at; adj[a].insert(b); adj[b].insert(a); lct.add(a, b); } // for (int c : color) cout << c << ' '; // cout << '\n'; } ++at; until[0] = at - 1; for (int i = 1; i < m; ++i) { while (at <= m) { pii p = edges[i - 1]; int a = p.first, b = p.second; // cout << i << ' ' << at << '\n'; if (lct.same(a, b) && color[a] == color[b] && at < m) { p = edges[at]; a = p.first, b = p.second; ++at; adj[a].erase(b); adj[b].erase(a); lct.erase(a, b); } else { adj[a].insert(b); adj[b].insert(a); if (!lct.same(a, b)) { int asz = lct.sz(a), bsz = lct.sz(b); if (asz < bsz) swap(a, b); color[b] = !color[a]; set<int> vis; vis.insert(b); queue<int> q; q.push(b); while (q.size()) { int v = q.front(); q.pop(); for (int u : adj[v]) { if (vis.count(u)) continue; vis.insert(u); color[u] = !color[v]; } } if (asz < bsz) swap(a, b); } lct.add(a, b); break; } // for (int c : color) cout << c << ' '; // cout << '\n'; } until[i] = at - 1; } // for (int num : until) cout << num + 1 << ' '; // cout << '\n'; for (int i = 0; i < q; ++i) { int a, b; cin >> a >> b; --a, --b; cout << (until[a] <= b ? "YES\n" : "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...