(UPD: 2024-12-04 14:48 UTC) Judge is not working due to Cloudflare incident. (URL) We can do nothing about it, sorry. After the incident is resolved, we will grade all submissions.

Submission #1119589

#TimeUsernameProblemLanguageResultExecution timeMemory
1119589Zero_OPCats or Dogs (JOI18_catdog)C++14
100 / 100
192 ms29044 KiB
#include <bits/stdc++.h> #define dbg(x) "[" #x " = " << (x) << "]" 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)); // cout << i << ' ' << j << ' ' << k << ' ' << l << " -> " << i << ' ' << l << '\n'; } } } } return c; } void debug(){ cout << "[" << a[0][0] << ", " << a[0][1] << ", " << a[1][0] << ", " << a[1][1] << "]\n"; } }; 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]; } void debug(int id, int l, int r){ cout << dbg(l) << dbg(r); st[id].debug(); if(l < r){ int mid = l + r >> 1; debug(id << 1, l, mid); debug(id << 1 | 1, mid + 1, r); } } } 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(); } void test(){ node a, b; a.a[0][0] = 0, a.a[1][1] = MAX, a.a[0][1] = MAX, a.a[1][0] = MAX; b.a[0][0] = MAX, b.a[1][1] = 0, b.a[0][1] = MAX, b.a[1][0] = MAX; node c = a + b; c.debug(); exit(0); } #ifdef LOCAL int main(){ ios_base::sync_with_stdio(0); cin.tie(0); freopen("task.inp", "r", stdin); freopen("task.out", "w", stdout); // test(); // return 0; int N; cin >> N; vector<int> A(N - 1), B(N - 1); for(int i = 0; i < N - 1; ++i){ cin >> A[i] >> B[i]; } initialize(N, A, B); int Q; cin >> Q; while(Q--){ int t, v; cin >> t >> v; if(t == 1) cout << cat(v) << '\n'; if(t == 2) cout << dog(v) << '\n'; if(t == 3) cout << neighbor(v) << '\n'; } return 0; } #endif //LOCAL

Compilation message (stderr)

catdog.cpp: In member function 'void segment_tree::update(int, int, int, int, int, int)':
catdog.cpp:52:25: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   52 |             int mid = l + r >> 1;
      |                       ~~^~~
catdog.cpp: In member function 'void segment_tree::build(int, int, int)':
catdog.cpp:66:25: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   66 |             int mid = l + r >> 1;
      |                       ~~^~~
catdog.cpp: In member function 'void segment_tree::debug(int, int, int)':
catdog.cpp:80:25: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   80 |             int mid = l + r >> 1;
      |                       ~~^~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...