Submission #1278492

#TimeUsernameProblemLanguageResultExecution timeMemory
1278492wonderfulCats or Dogs (JOI18_catdog)C++20
100 / 100
164 ms69064 KiB
#include "catdog.h" #include <bits/stdc++.h> using namespace std; typedef long long ll; #define MASK(i) (1ULL << (i)) #define GETBIT(mask, i) (((mask) >> (i)) & 1) #define ALL(v) (v).begin(), (v).end() template<class T1, class T2> bool maximize(T1 &a, T2 b){ if (a < b){ a = b; return true; } return false; } template<class T1, class T2> bool minimize(T1 &a, T2 b){ if (a > b){ a = b; return true; } return false; } const ll INF = 1e18; int n; vector<int> adj[1000005]; int child[1000005], big[1000005]; int par[1000005], head[1000005], rev[1000005], pos[1000005], curPos, sz[1000005]; int cur[1000005]; void dfs(int u, int p){ child[u] = 1; big[u] = -1; for (auto v : adj[u]){ if (v == p) continue; dfs(v, u); child[u] += child[v]; if (big[u] == -1 || child[big[u]] < child[v]) big[u] = v; } } void decompose(int u, int h, int p){ pos[u] = ++curPos; par[u] = p; rev[curPos] = u; head[u] = h; sz[h]++; if (big[u] != -1) decompose(big[u], h, u); for (auto v : adj[u]){ if (v == p || v == big[u]) continue; decompose(v, v, u); } } struct Node{ ll x[2][2]; }; Node combine(Node a, Node b){ Node res; for (int i = 0; i <= 1; i++) for (int j = 0; j <= 1; j++) res.x[i][j] = 1e9; for (int i = 0; i <= 1; i++) for (int j = 0; j <= 1; j++) for (int k = 0; k <= 1; k++) for (int l = 0; l <= 1; l++) res.x[i][j] = min(res.x[i][j], a.x[i][k] + b.x[l][j] + (k ^ l)); return res; } struct SegTree{ vector<Node> st; int n; void init(int _n){ n = _n; st.assign(4*n+5, {}); } void build(int id, int l, int r){ if (l == r){ st[id].x[0][0] = st[id].x[1][1] = 0; st[id].x[0][1] = st[id].x[1][0] = 1e9; return; } int mid = (l + r) >> 1; build(id*2, l, mid); build(id*2+1, mid+1, r); st[id] = combine(st[id*2], st[id*2+1]); } void update(int id, int l, int r, int p, int va, int vb){ if (l == r){ st[id].x[0][0] += va; st[id].x[1][1] += vb; return; } int mid = (l + r) >> 1; if (p <= mid) update(id*2, l, mid, p, va, vb); else update(id*2+1, mid+1, r, p, va, vb); st[id] = combine(st[id*2], st[id*2+1]); } pair<int,int> get(){ int c = min(st[1].x[0][0], st[1].x[0][1]); int d = min(st[1].x[1][1], st[1].x[1][0]); return {min(c, d+1), min(c+1, d)}; } }; SegTree seg[1000005]; void updatePath(int u, int va, int vb){ while (u){ int h = head[u]; auto [c, d] = seg[h].get(); seg[h].update(1, 1, sz[h], pos[u]-pos[h]+1, va, vb); auto [c1, d1] = seg[h].get(); va = c1 - c; vb = d1 - d; u = par[h]; } } int cat(int x){ cur[x] = 1; updatePath(x, 0, 1e9); auto [c, d] = seg[1].get(); return min(c, d); } int dog(int x){ cur[x] = 2; updatePath(x, 1e9, 0); auto [c, d] = seg[1].get(); return min(c, d); } int neighbor(int x){ updatePath(x, -1e9*(cur[x] != 1), -1e9*(cur[x] != 2)); cur[x] = 0; auto [c, d] = seg[1].get(); return min(c, d); } 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].push_back(v); adj[v].push_back(u); } dfs(1, 0); decompose(1, 1, 0); for (int i = 1; i <= n; i++){ if (head[i] == i){ seg[i].init(sz[i]); seg[i].build(1, 1, sz[i]); } } }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...