Submission #1283002

#TimeUsernameProblemLanguageResultExecution timeMemory
1283002daotuankhoiCats or Dogs (JOI18_catdog)C++20
100 / 100
140 ms25524 KiB
#include <bits/stdc++.h> using namespace std; #define ll long long const int MAXN = 1e5 + 5; vector<int> g[MAXN]; const int INF = 1e9; int sz[MAXN], head[MAXN], heavy[MAXN], par[MAXN], in[MAXN], val[MAXN]; /// 0: cat, 1: dog struct Node { int dp[2][2]; Node() { dp[0][0] = dp[1][1] = 0; dp[0][1] = dp[1][0] = INF; } }; Node comb(Node a, Node b) { Node res; res.dp[0][0] = res.dp[1][0] = res.dp[0][1] = res.dp[1][1] = INF; for (int i = 0; i < 2; i++) { for (int j = 0; j < 2; j++) { if (a.dp[i][j] < INF) { for (int u = 0; u < 2; u++) { for (int v = 0; v < 2; v++) { if (b.dp[u][v] < INF) { res.dp[i][v] = min(res.dp[i][v], a.dp[i][j] + b.dp[u][v] + (j ^ u)); } } } } } } return res; } struct SegTree { vector<Node> tree; void init(int N) { tree.resize(N * 4); } void update(int id, int l, int r, int p, int cat, int dog) { if (p < l || r < p) return; if (l == r) { tree[id].dp[0][0] += cat; tree[id].dp[1][1] += dog; return; } int mid = (l + r) >> 1; update(id << 1, l, mid, p, cat, dog); update(id << 1 | 1, mid + 1, r, p, cat, dog); tree[id] = comb(tree[id << 1], tree[id << 1 | 1]); } pair<int, int> get(void) { Node ans = tree[1]; int cat = min({ans.dp[0][0], ans.dp[0][1], ans.dp[1][0] + 1, ans.dp[1][1] + 1}); int dog = min({ans.dp[1][0], ans.dp[1][1], ans.dp[0][0] + 1, ans.dp[0][1] + 1}); return {cat, dog}; } } st[MAXN]; void dfs(int u, int p) { sz[u] = 1; for (int v : g[u]) { if (v != p) { par[v] = u; dfs(v, u); sz[u] += sz[v]; if (heavy[u] == 0 || sz[v] > sz[heavy[u]]) heavy[u] = v; } } } void build(int u, int h) { head[u] = h; in[u] = ++sz[h]; if (heavy[u]) build(heavy[u], h); for (int v : g[u]) { if (v != par[u] && v != heavy[u]) { build(v, v); } } } void initialize(int N, vector<int> A, vector<int> B) { for (int i = 0; i < N - 1; i++) { g[A[i]].emplace_back(B[i]); g[B[i]].emplace_back(A[i]); } dfs(1, 0); for (int i = 1; i <= N; i++) sz[i] = 0; build(1, 1); for (int i = 1; i <= N; i++) if (head[i] == i) { st[head[i]].init(sz[head[i]]); } } void upd(int u, int cat, int dog) { while (u) { auto lst = st[head[u]].get(); st[head[u]].update(1, 1, sz[head[u]], in[u], cat, dog); auto cur = st[head[u]].get(); cat = cur.first - lst.first; dog = cur.second - lst.second; u = par[head[u]]; } } int cat(int v) { val[v] = 1; upd(v, 0, INF); Node res = st[1].tree[1]; return min({res.dp[0][0], res.dp[0][1], res.dp[1][0], res.dp[1][1]}); } int dog(int v) { val[v] = 2; upd(v, INF, 0); Node res = st[1].tree[1]; return min({res.dp[0][0], res.dp[0][1], res.dp[1][0], res.dp[1][1]}); } int neighbor(int v) { if (val[v] == 1) { upd(v, 0, -INF); } else { upd(v, -INF, 0); } val[v] = 0; Node res = st[1].tree[1]; return min({res.dp[0][0], res.dp[0][1], res.dp[1][0], res.dp[1][1]}); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...