Submission #126573

#TimeUsernameProblemLanguageResultExecution timeMemory
126573WhipppedCreamCats or Dogs (JOI18_catdog)C++17
100 / 100
890 ms34436 KiB
#include <bits/stdc++.h> #pragma GCC optimize ("O3") #pragma GCC target ("sse4") using namespace std; #define X first #define Y second #define pb push_back typedef pair<int, int> ii; typedef long long ll; const int maxn = 1e5+5; vector<int> adj[maxn]; int n; int par[22][maxn]; int dep[maxn]; int cnt[maxn]; int pref[maxn]; int pos[maxn]; int head[maxn]; int tail[maxn]; ii per[maxn]; void dfs(int u = 1, int p = 0) { dep[u] = dep[p]+1; par[0][u] = p; cnt[u] = 1; for(int i = 1; i<= 20; i++) par[i][u] = par[i-1][par[i-1][u]]; ii big = {0, -1}; for(int v : adj[u]) { if(v == p) continue; dfs(v, u); cnt[u] += cnt[v]; big = max(big, {cnt[v], v}); } pref[u] = big.Y; } void hld() { int tim = 1; for(int i = 1; i<= n; i++) { if(pref[par[0][i]] == i) continue; for(int j = i; j != -1; j = pref[j]) { head[j] = i; pos[j] = tim++; tail[i] = j; } } } struct node { int val[4]; node() { memset(val, 0, sizeof val); } node operator + (node &other) const { node res; for(int i = 0; i< 4; i++) res.val[i] = 1e9; for(int i = 0; i< 4; i++) { int b1 = (i&2)> 0; int b2 = (i&1)> 0; for(int j = 0; j< 4; j++) { int b3 = (j&2)> 0; int b4 = (j&1)> 0; res.val[b1*2+b4] = min(res.val[b1*2+b4], val[i]+other.val[j]+(b2!= b3)); } } return res; } }; node st[4*maxn]; void build(int p = 1, int L = 1, int R = n) { if(L == R) { st[p] = node(); st[p].val[1] = st[p].val[2] = 1e9; return; } int M = (L+R)>>1; build(p<<1, L, M); build(p<<1|1, M+1, R); st[p] = st[p<<1]+st[p<<1|1]; } void update(int x, ii v, int p = 1, int L = 1, int R = n) { if(L == R) { st[p].val[0] += v.X; st[p].val[3] += v.Y; return; } int M = (L+R)>>1; if(x<= M) update(x, v, p<<1, L, M); else update(x, v, p<<1|1, M+1, R); st[p] = st[p<<1] + st[p<<1|1]; } node ask(int i, int j, int p = 1, int L = 1, int R = n) { if(i> R || j< L) { node res; res.val[1] = res.val[2] = 1e9; return res; } if(i<= L && R<= j) return st[p]; int M = (L+R)>>1; node x = ask(i, j, p<<1, L, M); node y = ask(i, j, p<<1|1, M+1, R); return x+y; } void change(int u, ii x) { // printf("change %d\n", u); while(u) { // printf("go %d {%d, %d}\n", u, x.X, x.Y); update(pos[u], x); node tmp = ask(pos[head[u]], pos[tail[head[u]]]); // for(int i = 0; i< 4; i++) printf("%d ", tmp.val[i]); // printf("\n"); int v0 = min(tmp.val[0], tmp.val[1]); int v1 = min(tmp.val[2], tmp.val[3]); ii res = {min(v0, v1+1), min(v0+1, v1)}; x = ii(res.X-per[head[u]].X, res.Y-per[head[u]].Y); per[head[u]] = res; u = par[0][head[u]]; } } int gimme() { node res = ask(pos[1], pos[tail[1]]); return *min_element(res.val, res.val+4); } void initialize(int N, vector<int> A, vector<int> B) { n = N; for(int i = 0; i< n-1; i++) { adj[A[i]].pb(B[i]); adj[B[i]].pb(A[i]); } dfs(); hld(); build(); } int stat[maxn]; int cat(int u) { stat[u] = 1; change(u, {0, 1e9}); return gimme(); } int dog(int u) { stat[u] = 2; change(u, {1e9, 0}); return gimme(); } int neighbor(int u) { if(stat[u] == 1) change(u, {0, -1e9}); if(stat[u] == 2) change(u, {-1e9, 0}); stat[u] = 0; return gimme(); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...