Submission #1299251

#TimeUsernameProblemLanguageResultExecution timeMemory
1299251efegJoker (BOI20_joker)C++20
100 / 100
317 ms8956 KiB
#include <bits/stdc++.h> using namespace std; #define pb push_back #define eb emplace_back #define F first #define S second typedef pair<int,int> ii; typedef tuple<int,int,int> iii; template<typename T> using vec = vector<T>; using i64 = long long; struct DSU{ int n; vec<int> dsu,dist; stack<iii> history; DSU(int n) : n(n){ dsu.assign(n,-1); dist.assign(n,0); } ii find(int x){ int d = 0; while (dsu[x] >= 0){ d ^= dist[x]; x = dsu[x]; } return {x,d}; } bool merge(int x,int y){ int distx,disty,px,py; tie(px,distx) = find(x); tie(py,disty) = find(y); if (px == py) { if (distx == disty){ return false; } return true; } if (dsu[px] > dsu[py]) swap(px,py); history.push({px,py,dsu[py]}); dsu[px] += dsu[py]; dsu[py] = px; dist[py] = (distx + 1 + disty) & 1; return true; } int snapshot(){ return history.size(); } void rollback(int until){ while (snapshot() > until){ int root,child,childsiz; tie(root,child,childsiz) = history.top(); history.pop(); dsu[child] = childsiz; dsu[root] -= childsiz; dist[child] = 0; } } }; int n,m,q; vec<ii> edges; vec<ii> queries; vec<bool> ans; DSU dsu(2e5 + 100); vec<int> last; void dac(int l,int r,int y){ if (l == r) return; int m = (l + r) / 2; int siz1 = dsu.snapshot(); for (int i = l; i < m; i++) dsu.merge(edges[i].F,edges[i].S); int siz2 = dsu.snapshot(); int tmpy = y; while (tmpy > m && dsu.merge(edges[tmpy-1].F,edges[tmpy-1].S)) tmpy--; last[m] = tmpy; dsu.rollback(siz2); dsu.merge(edges[m].F,edges[m].S); dac(m+1,r,y); dsu.rollback(siz1); for (int i = tmpy; i < y; i++){ dsu.merge(edges[i].F,edges[i].S); } dac(l,m,tmpy); dsu.rollback(siz1); } int main(){ ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); cin >> n >> m >> q; ans.assign(q + 1,false); last.assign(m + 1,-1); for (int i = 0; i < m; i++){ int a,b; cin >> a >> b; a--; b--; edges.eb(a,b); } for (int i = 0; i < q; i++){ int l,r; cin >> l >> r; l--; r--; queries.eb(l,r); } int x = 0; while (x < m && dsu.merge(edges[x].F,edges[x].S)) x++; for (int i = x + 1; i < m; i++) last[i] = m+1; dsu.rollback(0); dac(0,min(m,x+1),m); for (int i = 0; i < q; i++){ int l,r; tie(l,r) = queries[i]; if (last[l] <= r+1) cout << "NO" << endl; else cout << "YES" << 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...