Submission #1146199

#TimeUsernameProblemLanguageResultExecution timeMemory
1146199kh0iSpring cleaning (CEOI20_cleaning)C++20
100 / 100
119 ms17988 KiB
#include "bits/stdc++.h" using namespace std; #ifdef LOCAL #include "debug.h" #else #define debug(...) #endif using ll = long long; using pii = pair<int, int>; #define F first #define S second #define sz(x) (int)((x).size()) #define all(x) (x).begin(), (x).end() mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()); ll get_rand(ll l, ll r) { assert(l <= r); return uniform_int_distribution<ll> (l, r)(rng); } const int N = 1e5 + 3; int n, q, root; vector<int> g[N]; int leaf[N]; bool is_leaf[N]; int pos[N], p[N], head[N], cur_pos, h[N], sz[N]; namespace ST{ int st[N << 2], lz[N << 2]; void flip_node(int id, int l, int r){ lz[id] ^= 1; st[id] = (r - l + 1) - st[id]; } void down(int id, int l, int r){ int mid = (l + r) >> 1; flip_node(id << 1, l, mid); flip_node(id << 1 | 1, mid + 1, r); lz[id] = 0; } void update(int pos, int val, int id = 1, int l = 1, int r = n){ if(l == r){ st[id] = val; return; } int mid = (l + r) >> 1; if(pos <= mid) update(pos, val, id << 1, l, mid); else update(pos, val, id << 1 | 1, mid + 1, r); st[id] = st[id << 1] + st[id << 1 | 1]; } void flip(int tl, int tr, int id = 1, int l = 1, int r = n){ if(l > tr or tl > r) return; if(tl <= l and r <= tr){ flip_node(id, l, r); return; } int mid = (l + r) >> 1; if(lz[id]) down(id, l, r); flip(tl, tr, id << 1, l, mid); flip(tl, tr, id << 1 | 1, mid + 1, r); st[id] = st[id << 1] + st[id << 1 | 1]; } } void dfs(int u, int pre = -1){ is_leaf[u] = (sz(g[u]) == 1); leaf[u] = is_leaf[u]; sz[u] = 1; for(int v : g[u]){ if(v == pre) continue; h[v] = h[u] + 1; p[v] = u; dfs(v, u); sz[u] += sz[v]; leaf[u] += leaf[v]; } } void hld(int u, int cur_head, int pre = -1){ pos[u] = ++cur_pos; head[u] = cur_head; int nx = -1; for(int v : g[u]) if(v != pre and (nx == -1 or sz[nx] < sz[v])) nx = v; if(nx != -1) hld(nx, cur_head, u); for(int v : g[u]) if(v != pre and v != nx) hld(v, v, u); } void flip(int u){ while(head[u] != root){ ST::flip(pos[head[u]], pos[u]); u = p[head[u]]; } ST::flip(2, pos[u]); } void solve(){ cin >> n >> q; for(int i = 1; i < n; ++i){ int u, v; cin >> u >> v; g[u].push_back(v); g[v].push_back(u); } for(int i = 1; i <= n; ++i){ if(sz(g[i]) > 1){ root = i; break; } } dfs(root); hld(root, root); for(int i = 1; i <= n; ++i) if(i != root) ST::update(pos[i], leaf[i] % 2 == 0); while(q--){ int d; cin >> d; int cnt = leaf[root] + d; vector<int> old_leaf, changed; for(int i = 1; i <= d; ++i){ int a; cin >> a; if(is_leaf[a]){ is_leaf[a] = 0, --cnt; old_leaf.push_back(a); } else{ changed.push_back(a); flip(a); } } if(cnt & 1) cout << -1 << '\n'; else cout << n - 1 + d + ST::st[1] << '\n'; for(int i : old_leaf) is_leaf[i] = 1; for(int i : changed) flip(i); } } int32_t main() { cin.tie(nullptr)->sync_with_stdio(0); #define task "troll" if(fopen(task".inp", "r")){ freopen(task".inp", "r", stdin); freopen(task".out", "w", stdout); } int test = 1; // cin >> test; for(int i = 1; i <= test; ++i){ // cout << "Case #" << i << ": "; solve(); } #ifdef LOCAL cerr << "\n[Time]: " << 1000.0 * clock() / CLOCKS_PER_SEC << " ms.\n"; #endif return 0; }

Compilation message (stderr)

cleaning.cpp: In function 'int32_t main()':
cleaning.cpp:171:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  171 |         freopen(task".inp", "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
cleaning.cpp:172:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
  172 |         freopen(task".out", "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
#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...