Submission #1043669

#TimeUsernameProblemLanguageResultExecution timeMemory
1043669myst6Spring cleaning (CEOI20_cleaning)C++14
70 / 100
1043 ms22096 KiB
#include <bits/stdc++.h> using namespace std; int main() { // take inputs cin.tie(0)->sync_with_stdio(0); int N, Q; cin >> N >> Q; vector<vector<int>> adj(2e5); for (int i=0; i<N-1; i++) { int u, v; cin >> u >> v; u--, v--; adj[u].push_back(v); adj[v].push_back(u); } // analyse tree vector<int> parent(2e5, -1); vector<int> depth(2e5, 0); vector<int> parity(2e5, 0); vector<int> cost(2e5, 0); set<int> upd; auto dfs = [&](auto &self, int x) -> void { for (int y : adj[x]) { if (y != parent[x]) { parent[y] = x; depth[y] = depth[x] + 1; self(self, y); parity[x] ^= parity[y]; cost[x] += cost[y] + 1; if (parity[y] == 0) cost[x] += 1; } } if (adj[x].size() == 1) parity[x] ^= 1; }; dfs(dfs, 0); // check for subtask 6 bool subtask_6 = true; vector<vector<int>> queries(Q); for (int i=0; i<Q; i++) { int D; cin >> D; if (D != 1) subtask_6 = false; for (int j=0; j<D; j++) { int a; cin >> a; queries[i].push_back(a); } } if (subtask_6) { vector<int> n_odd(N), n_even(N); auto dfs = [&](auto &self, int x) -> void { if (parity[x] == 1) n_odd[x] += 1; if (parity[x] == 0) n_even[x] += 1; for (int y : adj[x]) { if (y != parent[x]) { n_odd[y] += n_odd[x]; n_even[y] += n_even[x]; self(self, y); } } }; dfs(dfs, 0); for (int i=0; i<Q; i++) { int x = queries[i][0]; x--; if (adj[x].size() == 1) { if (parity[0] == 1) { cout << "-1\n"; } else { cout << cost[0] + 1 << "\n"; } } else { if (parity[0] == 0) { cout << "-1\n"; } else { cout << cost[0] + n_odd[x] - n_even[x] << "\n"; } } } return 0; } // handle queries for (int i=0; i<Q; i++) { set<pair<int,int>> upd; for (int j=0; j<queries[i].size(); j++) { int a = queries[i][j]; a--; adj[a].push_back(N + j); parity[N + j] = 1; cost[N + j] = 0; upd.insert({depth[a], a}); } set<pair<int,int>> upd_copy(upd); while (!upd.empty()) { auto it = prev(upd.end()); int d = it->first, x = it->second; upd.erase(it); if (x == -1) continue; parity[x] = 0; cost[x] = 0; for (int y : adj[x]) { if (y != parent[x]) { parity[x] ^= parity[y]; cost[x] += cost[y] + 1; if (parity[y] == 0) cost[x] += 1; } } if (adj[x].size() == 1) parity[x] ^= 1; upd.insert({d - 1, parent[x]}); } // if the root of the tree has odd parity, it is impossible to clean, otherwise output its cost if (parity[0] == 1) { cout << "-1\n"; } else { cout << cost[0] << "\n"; } if (i == Q - 1) continue; // no need to reverse changes on last query // reverse changes while (!upd_copy.empty()) { auto it = prev(upd_copy.end()); int d = it->first, x = it->second; upd_copy.erase(it); if (x == -1) continue; while (adj[x].back() >= N) adj[x].pop_back(); parity[x] = 0; cost[x] = 0; for (int y : adj[x]) { if (y != parent[x]) { parity[x] ^= parity[y]; cost[x] += cost[y] + 1; if (parity[y] == 0) cost[x] += 1; } } if (adj[x].size() == 1) parity[x] ^= 1; upd_copy.insert({d - 1, parent[x]}); } } return 0; }

Compilation message (stderr)

cleaning.cpp: In function 'int main()':
cleaning.cpp:91:24: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   91 |         for (int j=0; j<queries[i].size(); j++) {
      |                       ~^~~~~~~~~~~~~~~~~~
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...