Submission #58582

#TimeUsernameProblemLanguageResultExecution timeMemory
58582imeimi2000Cats or Dogs (JOI18_catdog)C++17
100 / 100
418 ms81468 KiB
#include "catdog.h" #include <algorithm> #include <functional> using namespace std; typedef pair<int, int> pii; typedef long long llong; const llong inf = 1e16; const int MAXN = 1e6; struct node { llong val[2][2]; node() { val[0][0] = val[1][1] = 0; val[0][1] = val[1][0] = inf; } node operator+(const node &p) const { node ret; for (int i = 0; i < 2; ++i) { for (int j = 0; j < 2; ++j) { ret.val[i][j] = inf; for (int k = 0; k < 2; ++k) { for (int l = 0; l < 2; ++l) { ret.val[i][j] = min(ret.val[i][j] , val[i][k] + p.val[l][j] + (k ^ l)); } } } } return ret; } }; struct segtree { vector<node> val; int sz; void init(int i, int s, int e) { if (s == e) return; int m = (s + e) / 2; init(i << 1, s, m); init(i << 1 | 1, m + 1, e); val[i] = val[i << 1] + val[i << 1 | 1]; } void init(int _sz) { int s = 1; sz = _sz; while (s < (sz << 1)) s <<= 1; val.resize(s); init(1, 1, sz); } void update(int i, int s, int e, int x, llong v0, llong v1) { if (s == e) { val[i].val[0][0] += v0; val[i].val[1][1] += v1; return; } int m = (s + e) / 2; if (x <= m) update(i << 1, s, m, x, v0, v1); else update(i << 1 | 1, m + 1, e, x, v0, v1); val[i] = val[i << 1] + val[i << 1 | 1]; } void update(int i, llong x0, llong x1) { update(1, 1, sz, i, x0, x1); } pii query() const { int x = min(val[1].val[0][0], val[1].val[0][1]); int y = min(val[1].val[1][0], val[1].val[1][1]); return pii(min(x, y + 1), min(x + 1, y)); } } seg[100001]; int n; vector<int> edge[100001]; int sz[100001]; int pathPar[100001]; int pathPos[100001]; int par[100001]; int st[100001]; void dfsSize(int x, int p) { par[x] = p; sz[x] = 1; for (int i : edge[x]) { if (i == p) continue; dfsSize(i, x); sz[x] += sz[i]; } } void dfsDecomp(int x, int p) { int hpath = 0; for (int i : edge[x]) { if (i == p) continue; if (sz[x] <= (sz[i] << 1)) { hpath = i; break; } } if (hpath == 0) seg[pathPar[x]].init(pathPos[x]); for (int i : edge[x]) { if (i == p) continue; if (i != hpath) { pathPar[i] = i; pathPos[i] = 1; } else { pathPar[i] = pathPar[x]; pathPos[i] = pathPos[x] + 1; } dfsDecomp(i, x); } } void initialize(int N, vector<int> A, vector<int> B) { n = N; for (int i = 0; i < n - 1; ++i) { edge[A[i]].push_back(B[i]); edge[B[i]].push_back(A[i]); } dfsSize(1, 0); pathPar[1] = 1; pathPos[1] = 1; dfsDecomp(1, 0); } void update(int x, int v0, int v1) { while (x) { int path = pathPar[x]; int pr0, pr1, nx0, nx1; tie(pr0, pr1) = seg[path].query(); seg[path].update(pathPos[x], v0, v1); tie(nx0, nx1) = seg[path].query(); v0 = nx0 - pr0; v1 = nx1 - pr1; x = par[pathPar[x]]; } } int getAns() { int x, y; tie(x, y) = seg[1].query(); return min(x, y); } int cat(int v) { st[v] = 1; update(v, MAXN, 0); return getAns(); } int dog(int v) { st[v] = 2; update(v, 0, MAXN); return getAns(); } int neighbor(int v) { if (st[v] == 1) update(v, -MAXN, 0); else update(v, 0, -MAXN); st[v] = 0; return getAns(); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...