Submission #765592

#TimeUsernameProblemLanguageResultExecution timeMemory
765592oyberJoker (BOI20_joker)C++14
71 / 100
2084 ms9748 KiB
#include <cstdio> #include <vector> #include <algorithm> #include <functional> #include <stack> using namespace std; vector<int> u; vector<int> s; vector<int> p; int find(int n) { if (u[n] == n) return n; return find(u[n]); } int parity(int n) { if (u[n] == n) return 0; return parity(u[n])^p[n]; } struct UniteInfo { int a; int b; int sa; }; UniteInfo unite(int a, int b) { int ap = find(a); int bp = find(b); if (s[bp] > s[ap]) { swap(a, b); swap(ap, bp); } u[bp] = ap; s[ap] += s[bp]; if (parity(a) == parity(b)) { p[bp] = 1; } else { p[bp] = 0; } return UniteInfo { ap, bp, s[ap] - s[bp], }; } void undo(UniteInfo info) { u[info.b] = info.b; s[info.a] = info.sa; p[info.b] = 0; } struct Query { int l; int r; int i; }; bool comp_query(Query q1, Query q2) { return q1.r > q2.r; } bool comp_query2(Query q1, Query q2) { return q1.l < q2.l; } int main() { int n, m, qn; scanf("%d %d %d", &n, &m, &qn); u.resize(n); s.resize(n, 1); p.resize(n); vector<pair<int, int>> e(m); for (int i = 0; i < m; i++) { int a, b; scanf("%d %d", &a, &b); a--;b--; e[i] = make_pair(a, b); //printf("%d %d %d\n", a, b, i); } vector<Query> q(qn); for (int i = 0; i < qn; i++) { int l, r; scanf("%d %d", &l, &r); l--;r--; q[i] = Query{l,r,i}; } sort(q.begin(), q.end(), comp_query2); int group_size = 1024; int group_num = (q[q.size()-1].l+group_size) / group_size; //printf("%d %d\n", int(q[q.size()-1].l), group_num); vector<vector<Query>> groups(group_num); int j = 0; for (int i = 0; i < group_num; i++) { while (j < qn) { if (q[j].l >= (i+1)*group_size) break; groups[i].push_back(q[j]); //printf("g: %d q: %d\n", i, q[j].i); j++; } sort(groups[i].begin(), groups[i].end(), comp_query); } stack<UniteInfo> infos; vector<bool> result(qn); for (int j = 0; j < group_num; j++) { //reset state for (int i = 0; i < n; i++) { u[i] = i; s[i] = 1; p[i] = 0; } bool l_cycle = false; int current_l = 0; for (; current_l < j*group_size; current_l++) { int a = e[current_l].first; int b = e[current_l].second; //printf("%d %d %d\n", current_l, a, b); if (find(a) == find(b)) { if (parity(a) == parity(b)) { l_cycle = true; break; } } else { unite(a, b); } } //printf("l: %d\n", current_l); int current_r = m-1; bool r_cycle = false; for (int i = 0; i < int(groups[j].size()); i++) { if (r_cycle || l_cycle) { result[groups[j][i].i] = true; continue; } int l = groups[j][i].l; int r = groups[j][i].r; //printf("%d: %d %d\n", i, l, r); while (current_r > r) { int a = e[current_r].first; int b = e[current_r].second; //printf("%d %d %d\n", current_r, a, b); if (find(a) == find(b)) { if (parity(a) == parity(b)) { r_cycle = true; break; } } else { unite(a, b); } current_r--; } if (r_cycle) { result[groups[j][i].i] = true; continue; } bool cycle = false; for (int c_l = current_l; c_l < l; c_l++) { int a = e[c_l].first; int b = e[c_l].second; //printf("%d %d %d\n", current_l, a, b); if (find(a) == find(b)) { if (parity(a) == parity(b)) { cycle = true; break; } } else { infos.push(unite(a, b)); } } if (cycle) { result[groups[j][i].i] = true; } while (infos.size() > 0) { undo(infos.top()); infos.pop(); } } } for (int i = 0; i < qn; i++) { if (result[i]) { printf("YES\n"); } else { printf("NO\n"); } } }

Compilation message (stderr)

Joker.cpp: In function 'int main()':
Joker.cpp:71:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   71 |     scanf("%d %d %d", &n, &m, &qn);
      |     ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
Joker.cpp:81:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   81 |         scanf("%d %d", &a, &b);
      |         ~~~~~^~~~~~~~~~~~~~~~~
Joker.cpp:90:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   90 |         scanf("%d %d", &l, &r);
      |         ~~~~~^~~~~~~~~~~~~~~~~
#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...