Submission #1326508

#TimeUsernameProblemLanguageResultExecution timeMemory
1326508DeathIsAweCats or Dogs (JOI18_catdog)C++20
0 / 100
12 ms14648 KiB
#include "catdog.h" #include <bits/stdc++.h> using namespace std; #define ff first #define ss second #define pb push_back #define pf push_front #define mp make_pair #define ll long long int parent[100001], depth[100001], heavy[100001], head[100001], pos[100001], revpos[100001], tail[100001]; vector<vector<int>> segment; //0 is dog dog, 1 is dog cat, 2 is cat dog, 3 is cat cat vector<vector<int>> graph; int curpos = 0, bottom = 0; vector<int> merge(vector<int> a, vector<int> b) { if (a[0] == -1) return b; if (b[0] == -1) return a; vector<int> bruh(4); bruh[0] = min(a[0] + b[0], min(a[0] + b[2] + 1, min(a[1] + b[0] + 1, a[1] + b[2]))); bruh[1] = min(a[0] + b[1], min(a[0] + b[3] + 1, min(a[1] + b[1] + 1, a[1] + b[3]))); bruh[2] = min(a[2] + b[0], min(a[2] + b[2] + 1, min(a[3] + b[0] + 1, a[3] + b[2]))); bruh[3] = min(a[2] + b[1], min(a[2] + b[3] + 1, min(a[3] + b[1] + 1, a[3] + b[3]))); return bruh; } void change(int pos, vector<int> val) { pos += 131072; segment[pos] = val; while (pos > 1) { pos /= 2; segment[pos] = merge(segment[2 * pos], segment[2 * pos + 1]); } } vector<int> segquery(int a, int b) { if (a > b) swap(a, b); a += 131072; b += 131072; vector<int> left(4, -1), right(4, -1); while (a <= b) { if (a % 2 == 1) left = merge(left, segment[a++]); if (b % 2 == 0) right = merge(segment[b--], right); a /= 2; b /= 2; } return merge(left, right); } int dfs(int v) { int size = 1; int max_c_size = 0; for (int c : graph[v]) { if (c != parent[v]) { parent[c] = v; depth[c] = depth[v] + 1; int c_size = dfs(c); size += c_size; if (c_size > max_c_size) max_c_size = c_size, heavy[v] = c; } } return size; } void decompose(int v, int h) { head[v] = h, pos[v] = curpos, revpos[curpos++] = v; if (heavy[v] != -1) decompose(heavy[v], h); for (int i : graph[v]) { if (i != parent[v] && i != heavy[v]) decompose(i, i); } } void process(int a, vector<int> newval) { vector<int> oldgroup = segquery(pos[tail[a]], pos[head[a]]); change(pos[a], newval); vector<int> newgroup = segquery(pos[tail[a]], pos[head[a]]); if (head[a] == 0) return; //cout << "ORIGINALVAL" << endl; //for (int i: segment[pos[a] + 131072]) cout << i << ' '; cout << endl; //cout << "OLDGROUP" << a << endl; //for (int i: oldgroup) cout << i << ' '; cout << endl; //cout << "NEWGROUP" << a << endl; //for (int i: newgroup) cout << i << ' '; cout << endl; int olddog = min(oldgroup[0], min(oldgroup[1], min(oldgroup[2] + 1, oldgroup[3] + 1))); int oldcat = min(oldgroup[0] + 1, min(oldgroup[1] + 1, min(oldgroup[2], oldgroup[3]))); int newdog = min(newgroup[0], min(newgroup[1], min(newgroup[2] + 1, newgroup[3] + 1))); int newcat = min(newgroup[0] + 1, min(newgroup[1] + 1, min(newgroup[2], newgroup[3]))); vector<int> changevec = segment[pos[parent[head[a]]] + 131072]; changevec[0] += newdog - olddog, changevec[3] += newcat - oldcat; process(parent[head[a]], changevec); } void initialize(int n, vector<int> arra, vector<int> arrb) { for (int i=0;i<n;i++) heavy[i] = -1; graph = vector<vector<int>> (n); for (int i=0;i<n-1;i++) { arra[i]--; arrb[i]--; graph[arra[i]].pb(arrb[i]); graph[arrb[i]].pb(arra[i]); } parent[0] = 0, depth[0] = 1; dfs(0); decompose(0, 0); //for (int i=0;i<n;i++) cout << pos[i] << ' '; cout << endl; //for (int i=0;i<n;i++) cout << revpos[i] << ' '; cout << endl; int curtail = revpos[n - 1]; for (int i=n-2;i>-1;i--) { if (head[revpos[i]] != head[revpos[i + 1]]) curtail = revpos[i]; tail[revpos[i]] = curtail; } segment = vector<vector<int>> (262144, vector<int>(4, 0)); for (int i=131072;i<262144;i++) segment[i][1] = 1000000000, segment[i][2] = 1000000000; for (int i=0;i<n;i++) if (head[i] == 0 && depth[i] > depth[bottom]) bottom = i; bottom = pos[bottom]; } int cat(int v) { v -= 1; vector<int> lmao = segment[pos[v] + 131072]; lmao[0] += 1000000000; process(v, lmao); lmao = segquery(0, bottom); //for (int i: segment[3 + 131072]) cout << i << ' '; cout << endl << endl; return *min_element(lmao.begin(), lmao.end()); } int dog(int v) { v -= 1; vector<int> lmao = segment[pos[v] + 131072]; lmao[3] += 1000000000; process(v, lmao); lmao = segquery(0, bottom); //for (int i: segment[3 + 131072]) cout << i << ' '; cout << endl << endl; return *min_element(lmao.begin(), lmao.end()); } int neighbor(int v) { v -= 1; vector<int> lmao = segment[pos[v] + 131072]; lmao[0] -= 1000000000; lmao[3] -= 1000000000; process(v, lmao); lmao = segquery(0, bottom); return *min_element(lmao.begin(), lmao.end()); }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...