Submission #102577

#TimeUsernameProblemLanguageResultExecution timeMemory
102577IOrtroiiiCats or Dogs (JOI18_catdog)C++14
100 / 100
513 ms26784 KiB
#include <bits/stdc++.h> #include "catdog.h" using namespace std; const int N = 100100; const int inf = 1e9; struct Arr { array<array<int, 2>, 2> a; Arr() { a[0][0] = a[0][1] = a[1][0] = a[1][1] = inf; }; array<int, 2>& operator [](int id) { return a[id]; } }; Arr mrg(Arr x,Arr y) { Arr z; 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) { z[i][l] = min(z[i][l], x[i][j] + (j ^ k) + y[k][l]); } } } } return z; } #define md ((l + r) >> 1) struct SegTree { vector<Arr> t; void resize(int n) { t.resize((n + 1) << 2); } void build(int v,int l,int r) { if (l == r) { t[v][0][0] = t[v][1][1] = 0; return; } build(v << 1, l, md); build(v << 1 | 1, md + 1, r); t[v] = mrg(t[v << 1], t[v << 1 | 1]); } void add(int v,int l,int r,int p,int v0,int v1) { if (p < l || p > r) return; if (l == r) { t[v][0][0] += v0; t[v][1][1] += v1; return; } add(v << 1, l, md, p, v0, v1); add(v << 1 | 1, md + 1, r, p, v0, v1); t[v] = mrg(t[v << 1], t[v << 1 | 1]); } } t[N]; int a[N]; vector<int> g[N]; int child[N]; int up[N], par[N]; int tin[N], tt; int ll[N], rr[N]; void dfs(int u) { child[u] = 1; for (int v : g[u]) { if (v != par[u]) { par[v] = u; dfs(v); child[u] += child[v]; } } } void hld(int u,int root) { up[u] = root; tin[u] = ++tt; int nxt = 0; for (int v : g[u]) { if (v != par[u]) { if (child[v] > child[nxt]) { nxt = v; } } } if (nxt) { hld(nxt, root); } for (int v : g[u]) { if (v != par[u] && v != nxt) { hld(v, v); } } } void initialize(int n, vector<int> a,vector<int> b) { for (int i = 0; i < n - 1; ++i) { g[a[i]].push_back(b[i]); g[b[i]].push_back(a[i]); } dfs(1); hld(1, 1); for (int i = 1; i <= n; ++i) ll[i] = n, rr[i] = 1; for (int i = 1; i <= n; ++i) { ll[up[i]] = min(ll[up[i]], tin[i]); rr[up[i]] = max(rr[up[i]], tin[i]); } for (int i = 1; i <= n; ++i) { if (up[i] == i) { t[i].resize(rr[i] - ll[i] + 1); t[i].build(1, ll[i], rr[i]); } } } void add(int u,int v0,int v1) { while (up[u] != up[1]) { int v = up[u]; int nw[2], nx[2]; nw[0] = nw[1] = inf; for (int i = 0; i < 2; ++i) { for (int j = 0; j < 2; ++j) { for (int k = 0; k < 2; ++k) { nw[i] = min(nw[i], (i ^ j) + t[v].t[1][j][k]); } } } t[v].add(1, ll[v], rr[v], tin[u], v0, v1); nx[0] = nx[1] = inf; for (int i = 0; i < 2; ++i) { for (int j = 0; j < 2; ++j) { for (int k = 0; k < 2; ++k) { nx[i] = min(nx[i], (i ^ j) + t[v].t[1][j][k]); } } } u = par[v], v0 = nx[0] - nw[0], v1 = nx[1] - nw[1]; } t[1].add(1, ll[1], rr[1], tin[u], v0, v1); } int go() { int ans = inf; for (int i = 0; i < 2; ++i) { for (int j = 0; j < 2; ++j) { ans = min(ans, t[1].t[1][i][j]); } } return ans; } int cat(int u) { a[u] = 0; add(u, 0, inf); return go(); } int dog(int u) { a[u] = 1; add(u, inf, 0); return go(); } int neighbor(int u) { if (a[u]) add(u, -inf, 0); else add(u, 0, -inf); return go(); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...