제출 #1216437

#제출 시각아이디문제언어결과실행 시간메모리
1216437badge881Cats or Dogs (JOI18_catdog)C++20
100 / 100
112 ms26440 KiB
#include <bits/stdc++.h> using namespace std; const int MAX = 1e5 + 5; int N, sz[MAX], head[MAX], par[MAX], heavy[MAX], pos[MAX], sz_chain[MAX], t[MAX]; vector<int> adj[MAX]; struct node { int a[2][2]; node() { for (int i = 0; i < 2; ++i) for (int j = 0; j < 2; ++j) a[i][j] = MAX; } friend node operator+(const node &a, const node &b) { node c; for (int i = 0; i < 2; ++i) for (int j = 0; j < 2; ++j) for (int k = 0; k < 2; ++k) for (int l = 0; l < 2; ++l) c.a[i][l] = min(c.a[i][l], a.a[i][j] + b.a[k][l] + (k != j)); return c; } }; struct segment_tree { vector<node> st; segment_tree(int n) : st(n << 2) {} segment_tree() : st(0) {} void update(int id, int l, int r, int pos, int v_cat, int v_dog) { if (l == r) { st[id].a[0][0] += v_cat; st[id].a[1][1] += v_dog; } else { int mid = l + r >> 1; if (pos <= mid) update(id << 1, l, mid, pos, v_cat, v_dog); else update(id << 1 | 1, mid + 1, r, pos, v_cat, v_dog); st[id] = st[id << 1] + st[id << 1 | 1]; } } void build(int id, int l, int r) { if (l == r) { st[id].a[0][0] = 0; st[id].a[1][1] = 0; st[id].a[0][1] = MAX; st[id].a[1][0] = MAX; } else { int mid = l + r >> 1; build(id << 1, l, mid); build(id << 1 | 1, mid + 1, r); st[id] = st[id << 1] + st[id << 1 | 1]; } } node get() { return st[1]; } } chains[MAX]; void dfs_sz(int u) { sz[u] = 1; for (int v : adj[u]) { adj[v].erase(find(adj[v].begin(), adj[v].end(), u)); par[v] = u; dfs_sz(v); sz[u] += sz[v]; if (sz[heavy[u]] < sz[v]) heavy[u] = v; } } void dfs_hld(int u, int hd) { head[u] = hd; pos[u] = ++sz_chain[hd]; if (heavy[u]) { dfs_hld(heavy[u], hd); for (int v : adj[u]) if (v != heavy[u]) dfs_hld(v, v); } } void initialize(int N, vector<int> A, vector<int> B) { ::N = N; for (int i = 0; i < N - 1; ++i) { int u = A[i], v = B[i]; adj[u].emplace_back(v); adj[v].emplace_back(u); } dfs_sz(1); dfs_hld(1, 1); for (int i = 1; i <= N; ++i) { if (head[i] == i) { chains[i] = segment_tree(sz_chain[i]); chains[i].build(1, 1, sz_chain[i]); } } } void modify(int u, int cat, int dog) { while (u > 0) { node cur = chains[head[u]].get(); int fcat = min({cur.a[0][0], cur.a[0][1], cur.a[1][0] + 1, cur.a[1][1] + 1}); int fdog = min({cur.a[1][0], cur.a[1][1], cur.a[0][0] + 1, cur.a[0][1] + 1}); chains[head[u]].update(1, 1, sz_chain[head[u]], pos[u], cat, dog); cur = chains[head[u]].get(); int gcat = min({cur.a[0][0], cur.a[0][1], cur.a[1][0] + 1, cur.a[1][1] + 1}); int gdog = min({cur.a[1][0], cur.a[1][1], cur.a[0][0] + 1, cur.a[0][1] + 1}); cat = gcat - fcat; dog = gdog - fdog; u = par[head[u]]; } } int answer() { node cur = chains[1].get(); int cat = min(cur.a[0][0], cur.a[0][1]); int dog = min(cur.a[1][0], cur.a[1][1]); return min(cat, dog); } int cat(int u) { modify(u, 0, MAX); t[u] = 1; return answer(); } int dog(int u) { modify(u, MAX, 0); t[u] = 2; return answer(); } int neighbor(int u) { if (t[u] == 1) modify(u, 0, -MAX); if (t[u] == 2) modify(u, -MAX, 0); t[u] = 0; return answer(); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...