Submission #72957

#TimeUsernameProblemLanguageResultExecution timeMemory
72957spacewalkerBall Machine (BOI13_ballmachine)C++14
16.11 / 100
1083 ms73280 KiB
#include <cstdio> #include <vector> #include <algorithm> #include <utility> #include <set> using namespace std; struct BallMachine { vector<vector<int>> tree, hldPaths; vector<int> highestFilled, par, pathIn, placeInPath, depth, st, blankChildCount; vector<bool> filled; set<pair<int, int>> leafSet; int root, t = 0; int getInfo(int i, int p, int level) { par[i] = p; depth[i] = level + 1; st[i] = t++; int stSize = 1, childCount = 0; int bestChild = -1, bcSize = -1; // printf("yeet %d\n", i); for (int c : tree[i]) { if (c != p) { ++childCount; int subtreeSize = getInfo(c, i, level + 1); if (subtreeSize > bcSize) { bestChild = c; bcSize = subtreeSize; } } } if (bestChild == -1) { pathIn[i] = hldPaths.size(); hldPaths.emplace_back(1, -1); hldPaths.back().push_back(i); highestFilled.push_back(0); placeInPath[i] = 1; leafSet.emplace(st[i], i); } else { pathIn[i] = pathIn[bestChild]; placeInPath[i] = hldPaths[pathIn[i]].size(); hldPaths[pathIn[i]].push_back(i); } blankChildCount[i] = childCount; return stSize; } BallMachine(vector<vector<int>> &tree, int &root) : tree(tree), par(tree.size()), pathIn(tree.size()), placeInPath(tree.size()), depth(tree.size()), st(tree.size()), blankChildCount(tree.size()), root(root), filled(tree.size(), false) { getInfo(root, -1, 0); } int addBall() { // returns where ball was added auto toFillPair = *leafSet.begin(); leafSet.erase(toFillPair); int vToFill = toFillPair.second; // update the HLD ++highestFilled[pathIn[vToFill]]; // update blankChildCount if (vToFill != root) { --blankChildCount[par[vToFill]]; // update leafset if (blankChildCount[par[vToFill]] == 0) { leafSet.emplace(st[par[vToFill]], par[vToFill]); } } filled[vToFill] = true; return vToFill; } int deleteBall(int x) { // returns # of shifted balls int vToBlank = -1; for (int cPath = pathIn[x];;) { if (hldPaths[cPath].back() == root || !filled[par[hldPaths[cPath].back()]]) { vToBlank = hldPaths[cPath][highestFilled[cPath]]; break; } else { cPath = pathIn[par[hldPaths[cPath].back()]]; } } // update filld filled[vToBlank] = false; // update bcc & leafset if (vToBlank != root) { if (blankChildCount[par[vToBlank]] == 0) { leafSet.erase({st[par[vToBlank]], par[vToBlank]}); } ++blankChildCount[par[vToBlank]]; } // update HLD --highestFilled[pathIn[vToBlank]]; // update leafset again leafSet.emplace(st[vToBlank], vToBlank); return depth[x] - depth[vToBlank]; } }; int main() { int n, q, root = 0; scanf("%d %d", &n, &q); vector<vector<int>> tree(n); for (int i = 0; i < n; ++i) { int par; scanf("%d", &par); --par; if (par >= 0) { tree[par].push_back(i); tree[i].push_back(par); } else { root = i; } } BallMachine bm(tree, root); for (int qta = 0; qta < q; ++qta) { int type, param; scanf("%d %d", &type, &param); if (type == 1) { int ans = -1; for (int rep = 1; rep <= param; ++rep) ans = bm.addBall(); printf("%d\n", ans + 1); } else { printf("%d\n", bm.deleteBall(--param)); } } return 0; }

Compilation message (stderr)

ballmachine.cpp: In constructor 'BallMachine::BallMachine(std::vector<std::vector<int> >&, int&)':
ballmachine.cpp:13:6: warning: 'BallMachine::root' will be initialized after [-Wreorder]
  int root, t = 0;
      ^~~~
ballmachine.cpp:11:15: warning:   'std::vector<bool> BallMachine::filled' [-Wreorder]
  vector<bool> filled;
               ^~~~~~
ballmachine.cpp:46:2: warning:   when initialized here [-Wreorder]
  BallMachine(vector<vector<int>> &tree, int &root) : tree(tree), par(tree.size()),
  ^~~~~~~~~~~
ballmachine.cpp: In function 'int main()':
ballmachine.cpp:95:27: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  int n, q, root = 0; scanf("%d %d", &n, &q);
                      ~~~~~^~~~~~~~~~~~~~~~~
ballmachine.cpp:98:17: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   int par; scanf("%d", &par);
            ~~~~~^~~~~~~~~~~~
ballmachine.cpp:109:25: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
   int type, param; scanf("%d %d", &type, &param);
                    ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...