Submission #578205

#TimeUsernameProblemLanguageResultExecution timeMemory
578205talant117408Spring cleaning (CEOI20_cleaning)C++17
100 / 100
282 ms23840 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef pair <int, int> pii; typedef pair <ll, ll> pll; #define long unsigned long #define pb push_back #define mp make_pair #define all(v) (v).begin(),(v).end() #define rall(v) (v).rbegin(),(v).rend() #define lb lower_bound #define ub upper_bound #define sz(v) int((v).size()) #define do_not_disturb ios::sync_with_stdio(0);cin.tie(0);cout.tie(0); #define endl '\n' const int N = 2e5+7; vector <vector <int>> graph(N); int root, subtree[N], depth[N], parent[N], added[N]; int turn[N]; int head[N], heavy[N], pos[N], t; ll ans; ll tree[N*4]; bool lz[N*4]; struct query { int saizu; vector <int> cling; query() { saizu = 0; } query(int n) { saizu = n; cling.resize(n); } }; void push(int v, int l, int r) { if (lz[v]) { tree[v] *= -1; if (l != r) { lz[v*2] ^= 1; lz[v*2+1] ^= 1; } lz[v] = 0; } } void build(int v, int l, int r) { if (l == r) { tree[v] = turn[l]; return; } int mid = (l+r) >> 1; build(v*2, l, mid); build(v*2+1, mid+1, r); tree[v] = tree[v*2]+tree[v*2+1]; } void update(int v, int l, int r, int ql, int qr) { push(v, l, r); if (ql > r || l > qr) return; if (ql <= l && r <= qr) { lz[v] ^= 1; push(v, l, r); return; } int mid = (l+r) >> 1; update(v*2, l, mid, ql, qr); update(v*2+1, mid+1, r, ql, qr); tree[v] = tree[v*2]+tree[v*2+1]; } ll get(int v, int l, int r, int ql, int qr) { push(v, l, r); if (ql > r || l > qr) return 0; if (ql <= l && r <= qr) return tree[v]; int mid = (l+r) >> 1; return get(v*2, l, mid, ql, qr)+get(v*2+1, mid+1, r, ql, qr); } ll get(int n, int x) { ll res = 0; while (head[n] != root) { res += get(1, 1, x, pos[head[n]], pos[n]); update(1, 1, x, pos[head[n]], pos[n]); n = parent[head[n]]; } res += get(1, 1, x, pos[root], pos[n]); update(1, 1, x, pos[root], pos[n]); return res; } void clear(int n, int x) { while (head[n] != root) { update(1, 1, x, pos[head[n]], pos[n]); n = parent[head[n]]; } update(1, 1, x, pos[root], pos[n]); } int dfs(int v, int p) { subtree[v] = (sz(graph[v]) == 1 ? 1 : 0); parent[v] = p; int saizu = 1; int mx_saizu = 0; for (auto to : graph[v]) { if (to == p) { continue; } depth[to] = depth[v] + 1; auto tmp = dfs(to, v); saizu += tmp; if (tmp > mx_saizu) { mx_saizu = tmp; heavy[v] = to; } subtree[v] += subtree[to]; } if (v != root) ans += 2 - (subtree[v] % 2); return saizu; } void decompose(int v, int h) { head[v] = h; pos[v] = ++t; if (heavy[v] != -1) decompose(heavy[v], h); for (auto to : graph[v]) { if (to != parent[v] && to != heavy[v]) { decompose(to, to); } } } void initiate(int n) { for (int i = 1; i <= n; i++) { heavy[i] = -1; if (sz(graph[i]) > 1) { root = i; } } dfs(root, root); decompose(root, root); for (int i = 1; i <= n; i++) { turn[pos[i]] = (subtree[i]&1 ? 1 : -1); } turn[pos[root]] = 0; build(1, 1, n); } void solve() { int n, q; cin >> n >> q; vector <query> queries; for (int i = 1; i < n; i++) { int a, b; cin >> a >> b; graph[a].pb(b); graph[b].pb(a); } for (int i = 0; i < q; i++) { int k; cin >> k; queries.pb(query(k)); for (int j = 0; j < k; j++) { cin >> queries[i].cling[j]; } } initiate(n); for (int test = 0; test < q; test++) { ll tmp = queries[test].saizu; int l = 0; auto leaves = queries[test].cling; for (auto p : leaves) { if (sz(graph[p]) == 1) { added[p]++; if (added[p] == 1) { continue; } } l++; tmp += get(p, n); } if ((subtree[root]+l)&1) cout << -1 << endl; else cout << ans+tmp << endl; for (auto p : leaves) { if (sz(graph[p]) == 1) { added[p]--; if (added[p] == 0) { continue; } } clear(p, n); } } } int main() { do_not_disturb int t = 1; //~ cin >> t; while (t--) { solve(); } return 0; } /* 7 5 1 2 1 3 2 4 2 5 3 6 3 7 1 1 2 1 1 2 7 7 2 6 7 2 4 7 */
#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...