Submission #558849

#TimeUsernameProblemLanguageResultExecution timeMemory
558849RaresFelixCats or Dogs (JOI18_catdog)C++17
100 / 100
639 ms25952 KiB
#include "catdog.h" #include <bits/stdc++.h> #define MN 100071 using namespace std; int n, Sz[MN]; vector<int> L[MN]; const int kInf = numeric_limits<int>::max() / 4; struct mat { int v[2][2]; mat() { v[0][0] = v[1][1] = 0; v[0][1] = v[1][0] = kInf; } mat(int a, int b, int c, int d) { v[0][0] = a, v[0][1] = b, v[1][0] = c, v[1][1] = d; } } I; void afis(mat a); namespace AINT { mat uni(const mat &a, const mat &b) { mat re(kInf, kInf, kInf, kInf); for(int i = 0; i < 2; ++i) for(int j = 0; j < 2; ++j) for(int k = 0; k < 2; ++k) for(int w = 0; w < 2; ++w) re.v[i][w] = min(re.v[i][w], a.v[i][j] + b.v[k][w] + (j ^ k)); return re; } mat V[4 * MN]; int len; void init() { //for(int i = 0; i < 4 * MN; ++i) V[i] = r0; } void update(int p, mat v, int u = 1, int s = 1, int d = len) { if(d < p || p < s) return; if(s == d) { V[u] = v; //printf("Starea nodului %d(%d, %d) din AINT:\n", u, s, d); afis(V[u]); //printf("||||||||||||||\n"); return; } update(p, v, u << 1, s, (s + d) >> 1); update(p, v, u << 1 | 1, ((s + d) >> 1) + 1, d); V[u] = uni(V[u << 1], V[u << 1 | 1]); //printf("Starea nodului %d(%d, %d) din AINT:\n", u, s, d); afis(V[u]); //printf("||||||||||||||\n"); } mat query(int l, int r, int u = 1, int s = 1, int d = len) { if(r < s || d < l) return I; if(l <= s && d <= r) { return V[u]; } int mij = (s + d) >> 1; if(r <= mij) return query(l, r, u << 1, s, (s + d) >> 1); if(mij < l) return query(l, r, u << 1 | 1, ((s + d) >> 1) + 1, d); return uni(query(l, r, u << 1, s, (s + d) >> 1), query(l, r, u << 1 | 1, ((s + d) >> 1) + 1, d)); } } int Par[MN], In[MN], Out[MN], tmr, Nxt[MN]; int CFD[MN][2]; //cost fii secundari int TipHut[MN]; void recalc_mat(int u) { mat re; if(TipHut[u] == 0) { re.v[0][0] = 0; re.v[1][1] = kInf; } if(TipHut[u] == 1) { re.v[0][0] = kInf; re.v[1][1] = 0; } if(TipHut[u] == 2) { re.v[0][0] = 0; re.v[1][1] = 0; } re.v[0][1] = kInf; re.v[1][0] = kInf; re.v[0][0] += CFD[u][0]; re.v[1][1] += CFD[u][1]; //printf(" !!! Pt nodul %d am recalc matricea:\n", u); afis(re); //printf("\n\n"); AINT::update(In[u], re); } void afis(mat a) { //printf("%d %d\n%d %d\n", a.v[0][0], a.v[0][1], a.v[1][0], a.v[1][1]); } void propag(int u, int factor) { while(u) { int head = Nxt[u]; int tail = Out[head]; int par = Par[head]; mat rez = AINT::query(In[head], In[tail]); //printf("u %d head %d tail %d par %d mat:\n", u, head, tail, par); afis(rez); //printf("---\n"); CFD[par][0] += factor * min(min(rez.v[0][0], rez.v[0][1]), 1 + min(rez.v[1][0], rez.v[1][1])); CFD[par][1] += factor * min(1 + min(rez.v[0][0], rez.v[0][1]), min(rez.v[1][0], rez.v[1][1])); if(factor == 1) recalc_mat(par); u = par; } } void update(int u) { //printf("Update la %d cu tip %d\n", u, TipHut[u]); propag(u, -1); recalc_mat(u); propag(u, 1); } void dfs_sz(int u, int p) { Sz[u] = 1; for(auto &it : L[u]) if(it != p) { dfs_sz(it, u); Sz[u] += Sz[it]; if(L[u][0] == p || Sz[it] > Sz[L[u][0]]) swap(it, L[u][0]); } } void dfs_hld(int u, int p) { Par[u] = p; In[u] = ++tmr; if(p) { Nxt[u] = (u == L[p][0] ? Nxt[p] : u); } else Nxt[u] = u; Out[Nxt[u]] = u; for(auto it : L[u]) if(it != p) dfs_hld(it, u); } void initialize(int N, std::vector<int> A, std::vector<int> B) { n = N; for(int i = 0; i <= n; ++i) TipHut[i] = 2; for(int i = 0; i < int(A.size()); ++i) L[A[i]].push_back(B[i]), L[B[i]].push_back(A[i]); dfs_sz(1, 0); AINT::init(); dfs_hld(1, 0); AINT::len = tmr; //printf("Nod %d S %d N %d P %d I %d\n", i, Sz[i], Nxt[i], Par[i], In[i]); } int rez() { return min(CFD[0][0], CFD[0][1]); } int cat(int v) { TipHut[v] = 0; update(v); return rez(); } int dog(int v) { TipHut[v] = 1; update(v); return rez(); } int neighbor(int v) { TipHut[v] = 2; update(v); return rez(); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...