# | Time | Username | Problem | Language | Result | Execution time | Memory |
---|---|---|---|---|---|---|---|
72957 | spacewalker | Ball Machine (BOI13_ballmachine) | C++14 | 1083 ms | 73280 KiB |
This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#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, ¶m);
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)
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|---|---|---|---|
Fetching results... |