Submission #895278

#TimeUsernameProblemLanguageResultExecution timeMemory
895278themm1Spring cleaning (CEOI20_cleaning)C++17
19 / 100
1066 ms21136 KiB
#include <bits/stdc++.h> using namespace std; // ordered set whith s.order_of_key(x) method, which returns rank of element x in set s /* #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> using namespace __gnu_pbds; typedef tree<int, null_type, less_equal<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set; */ // pair printing template <class T, class U> ostream& operator<<(ostream& out, const pair<T, U> &par) {out << "(" << par.first << "; " << par.second << ")"; return out;} // set printing template <class T> ostream& operator<<(ostream& out, const set<T> &cont) { out << "{"; for(const auto &x:cont) out << x << ", "; out << "}"; return out; } // map printing template <class T, class U> ostream& operator<<(ostream& out, const map<T, U> &cont) {out << "{"; for(const auto &x:cont) out << x << ", "; out << "}"; return out; } // unordered_set printing template <class T> ostream& operator<<(ostream& out, const unordered_set<T> &cont) {out << "{";for(const auto &x:cont) out << x << ", ";out << "}";return out;} // unordered_map printing template <class T, class U> ostream& operator<<(ostream& out, const unordered_map<T, U> &cont) {out << "{";for(const auto &x:cont) out << x << ", ";out << "}";return out;} // vector printing template<class T> ostream& operator<<(ostream& out, const vector<T> &cont){ out << "["; for (const auto &x:cont) out << x << ", "; out << "]"; return out;} #define print(x) cout << (x) << endl; #define dmp(x) cerr << #x << " = " << x << endl #define dmpn(x) cerr << #x << " = " << x << "; " #define dmpl(x) cerr << "Line " << __LINE__ << ": " << #x << " = " << x << endl using ll = long long; using ld = long double; using pii = pair<int, int>; using pll = pair<ll, ll>; #define pb push_back #define ff first #define ss second #define all(x) begin(x), end(x) #define sz(x) (int)x.size() #define contains(s,x) ((s).find(x) != (s).end()) const int MOD = 998244353; const int MXN = 200005; struct LazySegtree { int N; int sums[MXN], flipped[MXN]; LazySegtree(vector<int> &a) { N = pow(2, ceil(log2(sz(a)))); for (int i = 0; i < MXN; i++) { sums[i] = 0; flipped[i] = 0; } for (int i = 0; i < sz(a); i++) if (a[i]) lazy_update(i, i + 1, 0, N, 1); // dmp(sums); // dmp(flipped); } int get_sum(int idx, int i, int j) { if (flipped[idx]) return (j - i) - sums[idx]; return sums[idx]; } void push_lazy(int idx, int i, int j) { if (flipped[idx]) { flipped[idx * 2] ^= 1; flipped[idx * 2 + 1] ^= 1; flipped[idx] = 0; } } int query(int l, int r, int i, int j, int idx = 1) { // aktualny je cely v povodnom if (l <= i && j <= r) { return get_sum(idx, i, j); // prekryva sa } else if ((i <= l && l < j) || (i < r && r <= j)) { push_lazy(idx, i, j); int mid = (i + j) / 2; return query(l, r, i, mid, idx * 2) + query(l, r, mid, j, idx * 2 + 1); } return 0; } void lazy_update(int l, int r, int i, int j, int idx = 1) { if (l <= i && j <= r) { flipped[idx] ^= 1; } else if ((i <= l && l < j) || (i < r && r <= j)) { push_lazy(idx, i, j); int mid = (i + j) / 2; lazy_update(l, r, i, mid, idx * 2); lazy_update(l, r, mid, j, idx * 2 + 1); sums[idx] = get_sum(idx * 2, i, mid) + get_sum(idx * 2 + 1, mid, j); } } void print_row(int l, int r) { for (int i = l; i < r; i++) cout << query(i, i + 1, 0, N) << " "; cout << endl; } }; int N, Q; vector<vector<int>> g; vector<int> intimes, tops, is_evens, parents; int dfs1(int v, int p) { int size = 0, mx = 0, mxi = -1; is_evens[v] = (sz(g[v]) == 1) ? 0 : 1; parents[v] = p; for (int u : g[v]) if (u != p) { int usz = dfs1(u, v); if (usz > mx) { mx = usz; mxi = u; } size += usz; if (!is_evens[u]) is_evens[v] ^= 1; } if (mxi != -1 && mxi != 0) swap(g[v][0], g[v][mxi]); return size; } int dfs2(int v, int p, int time, int top) { intimes[v] = time; tops[v] = top; for (int i = 0; i < sz(g[v]); i++) if (g[v][i] != p) { int u = g[v][i]; if (i == 0) time = dfs2(u, v, time + 1, top); else time = dfs2(u, v, time + 1, u); } return time; } void solve() { cin >> N >> Q; g.assign(N, {}); is_evens.assign(N, 0); parents.assign(N, -1); intimes.assign(N, 0); tops.assign(N, 0); for (int i = 0; i < N - 1; i++) { int u, v; cin >> u >> v; u--; v--; g[u].pb(v); g[v].pb(u); } int root = 0, leaves = 0; vector<int> degrees(N, 0); for (int i = 0; i < N; i++) { if (sz(g[i]) > 1); // root = i; else leaves++; degrees[i] = sz(g[i]); } dfs1(root, -1); dfs2(root, -1, 0, root); vector<int> base(N, 0); for (int i = 0; i < N; i++) base[intimes[i]] = is_evens[i]; LazySegtree st(base); // st.print_row(0, N); while (Q--) { int K; cin >> K; bool even = ((leaves + K) % 2 == 0); map<int, int> m; for (int i = 0; i < K; i++) { int v; cin >> v; v--; m[v]++; } map<pii, int> updates; for (pii kv : m) { int v = kv.ff; if (sz(g[v]) == 1) even ^= 1; if ((sz(g[v]) == 1 && kv.ss % 2 == 1) || (sz(g[v]) != 1 && kv.ss % 2 == 0)) continue; while (v != -1) { pii pr = { intimes[tops[v]], intimes[v] + 1 }; updates[pr]++; v = parents[tops[v]]; } } // st.print_row(0, N); // dmp(updates); // st.print_base_row(0, N); for (auto kv : updates) if (kv.ss % 2 == 1) st.lazy_update(kv.ff.ff, kv.ff.ss, 0, st.N); if (!even) cout << -1 << endl; else { int even_cnt = st.query(0, N, 0, st.N); int ans = N + K - 2 + even_cnt; cout << ans << endl; } for (auto kv : updates) if (kv.ss % 2 == 1) st.lazy_update(kv.ff.ff, kv.ff.ss, 0, st.N); } } int32_t main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int t = 1; // cin >> t; while (t--) { solve(); } }
#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...