Submission #97655

#TimeUsernameProblemLanguageResultExecution timeMemory
97655Alexa2001Cats or Dogs (JOI18_catdog)C++17
100 / 100
1380 ms30752 KiB
#include "catdog.h" #include <bits/stdc++.h> #define left_son (node<<1) #define right_son ((node<<1)|1) #define mid ((st+dr)>>1) using namespace std; const int Nmax = 1e5 + 5, inf = 1e6; int n, tip[Nmax]; class SegmentTree { int *go[2][2]; public: void build(int nr) { int i, j; for(i=0; i<2; ++i) for(j=0; j<2; ++j) go[i][j] = new int [nr << 2]; } void build(int node, int st, int dr) { if(st == dr) { go[0][0][node] = go[1][1][node] = 0; go[0][1][node] = go[1][0][node] = inf; return; } build(left_son, st, mid); build(right_son, mid+1, dr); go[0][0][node] = go[1][1][node] = 0; go[0][1][node] = go[1][0][node] = 1; } void update(int node, int st, int dr, int pos, int a1, int a2) { if(st == dr) { go[0][0][node] += a1; go[1][1][node] += a2; return; } if(pos <= mid) update(left_son, st, mid, pos, a1, a2); else update(right_son, mid+1, dr, pos, a1, a2); int i, j, k, t; for(i=0; i<2; ++i) for(j=0; j<2; ++j) { int x = 10 * inf; for(k=0; k<2; ++k) for(t=0; t<2; ++t) x = min(x, go[i][k][left_son] + go[t][j][right_son] + (k != t)); go[i][j][node] = x; } } int query0() { return min(go[0][0][1], go[0][1][1]); } int query1() { return min(go[1][0][1], go[1][1][1]); } int query() { return min(query1(), query0()); } } aint[Nmax]; namespace hp { vector<int> v[Nmax], chain[Nmax]; int nr = 0; int w[Nmax], t[Nmax], pos[Nmax], where[Nmax]; void dfs(int node, int dad = 0) { w[node] = 1; t[node] = dad; for(auto it : v[node]) if(it != dad) { w[node] += w[it]; dfs(it, node); } } void make_chains(int node) { where[node] = nr; pos[node] = chain[nr].size(); chain[nr].push_back(node); int xson = -1; for(auto it : v[node]) if(it != t[node] && (xson == -1 || w[xson] < w[it])) xson = it; if(xson == -1) return; make_chains(xson); for(auto it : v[node]) if(it != t[node] && it != xson) { ++nr; make_chains(it); } } void prepare() { dfs(1); nr = 1; make_chains(1); int i; for(i=1; i<=nr; ++i) { aint[i].build(chain[i].size()); aint[i].build(1, 0, chain[i].size() - 1); } } void update(int node, int add1, int add2) { int T, ans0, ans1; int C = where[node]; T = t[chain[C][0]]; if(T) ans0 = aint[C].query0(), ans1 = aint[C].query1(); aint[C].update(1, 0, chain[C].size() - 1, pos[node], add1, add2); if(!T) return; int ans2, ans3; ans2 = aint[C].query0(); ans3 = aint[C].query1(); update(T, min(ans2, ans3 + 1) - min(ans0, ans1 + 1), min(ans2 + 1, ans3) - min(ans0 + 1, ans1)); } } void initialize(int N, vector<int> A, vector<int> B) { int i; n = N; for(i=0; i<n-1; ++i) { hp :: v[A[i]].push_back(B[i]); hp :: v[B[i]].push_back(A[i]); } hp :: prepare(); } int cat(int v) /// tip 1 { hp :: update(v, 0, inf); tip[v] = 1; return aint[1].query(); } int dog(int v) /// tip 2 { hp :: update(v, inf, 0); tip[v] = 2; return aint[1].query(); } int neighbor(int v) /// tip 0 { if(tip[v] == 1) hp :: update(v, 0, -inf); else hp :: update(v, -inf, 0); tip[v] = 0; return aint[1].query(); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...