Submission #666828

#TimeUsernameProblemLanguageResultExecution timeMemory
666828LFFBBall Machine (BOI13_ballmachine)C++14
100 / 100
642 ms26464 KiB
#include <iostream> #include <vector> #include <set> #include <algorithm> #define debug(args...) //printf(args) #define all(x) x.begin(),x.end() typedef long long llong; const int MAX_N = 1e5 + 10; const int MAX_Q = 1e5 + 10; const int LOG = 25; int n, q; int root; int currentPointer = 0; bool hasBall[MAX_N]; int parent[MAX_N]; std::vector<int> children[MAX_N]; bool marked[MAX_N]; void addChild(int x) { if (x == parent[x]) return; if (marked[x]) return; marked[x] = true; children[parent[x]].push_back(x); addChild(parent[x]); } void calculateChildren() { for (int i = 0; i < n; i++) { addChild(i); } } namespace Conversion { int currentLabel = 0; int label[MAX_N]; int unlabel[MAX_N]; int oldParent[MAX_N]; std::vector<int> oldChildren[MAX_N]; void calculateLabel(int node) { for (int child : children[node]) { calculateLabel(child); } label[node] = currentLabel; unlabel[currentLabel] = node; debug("relabling %d -> %d\n", node, currentLabel); currentLabel++; } void calculateLabels() { calculateLabel(root); } void relabel() { for (int i = 0; i < n; i++) { oldParent[i] = parent[i]; } for (int i = 0; i < n; i++) { parent[label[i]] = label[oldParent[i]]; } for (int i = 0; i < n; i++) { for (int child : children[i]) oldChildren[i].push_back(child); } for (int i = 0; i < n; i++) { children[label[i]].clear(); for (int child : oldChildren[i]) children[label[i]].push_back(label[child]); } } } int superParent[MAX_N][LOG]; void setupBinaryLifting() { for (int i = 0; i < n; i++) { superParent[i][0] = parent[i]; } superParent[root][0] = -1; for (int l = 1; l < LOG; l++) { for (int i = 0; i < n; i++) { if (superParent[i][l-1] == -1) superParent[i][l] = -1; else superParent[i][l] = superParent[ superParent[i][l-1] ][l-1]; } } } void fallPointer() { for (int child : children[currentPointer]) { if (hasBall[child]) continue; debug("falling pointer from %d to %d\n", currentPointer, child); currentPointer = child; fallPointer(); return; } debug("didnt fall pointer from %d\n", currentPointer); } int addBall() { debug("adding ball to %d\n", currentPointer); if (hasBall[currentPointer]) { printf("Something went wrong, tried to add ball to occupied spot(%d)\n", currentPointer); exit(1); } int answer = currentPointer; hasBall[currentPointer] = true; currentPointer = parent[currentPointer]; fallPointer(); return answer; } int addBalls(int x) { debug("adding %d balls\n", x); int answer; for (int i = 0; i < x; i++) answer = addBall(); return answer; } int removeBall(int x) { debug("removing ball %d\n", x); if (!hasBall[x]) { printf("Something went wrong, trying to remove ball from empty spot %d\n", x); exit(1); } int count = 0; for (int l = LOG-1; l >= 0; l--) { int y = superParent[x][l]; if (y == -1) continue; if (!hasBall[y]) continue; debug("changing %d to %d at l = %d\n", x, y, l); count += (1 << l); x = y; } hasBall[x] = false; if (x < currentPointer) currentPointer = x; debug("setting pointer to %d\n", currentPointer); return count; } int main() { scanf("%d %d", &n, &q); for (int i = 0; i < n; i++) { scanf("%d", &parent[i]); parent[i]--; if (parent[i] == -1) { parent[i] = i; root = i; } } calculateChildren(); Conversion::calculateLabels(); Conversion::relabel(); root = Conversion::label[root]; setupBinaryLifting(); for (int query = 0; query < q; query++) { debug("----- query %d -----\n", query); int type, x; scanf("%d %d", &type, &x); if (type == 1) { int answer = addBalls(x); printf("%d\n", Conversion::unlabel[answer] + 1); } else if (type == 2) { int answer = removeBall(Conversion::label[x - 1]); printf("%d\n", answer); } } }

Compilation message (stderr)

ballmachine.cpp: In function 'int main()':
ballmachine.cpp:149:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  149 |     scanf("%d %d", &n, &q);
      |     ~~~~~^~~~~~~~~~~~~~~~~
ballmachine.cpp:152:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  152 |         scanf("%d", &parent[i]);
      |         ~~~~~^~~~~~~~~~~~~~~~~~
ballmachine.cpp:169:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  169 |         scanf("%d %d", &type, &x);
      |         ~~~~~^~~~~~~~~~~~~~~~~~~~
ballmachine.cpp: In function 'int addBalls(int)':
ballmachine.cpp:121:12: warning: 'answer' may be used uninitialized in this function [-Wmaybe-uninitialized]
  121 |     return answer;
      |            ^~~~~~
ballmachine.cpp: In function 'int main()':
ballmachine.cpp:172:54: warning: 'answer' may be used uninitialized in this function [-Wmaybe-uninitialized]
  172 |             printf("%d\n", Conversion::unlabel[answer] + 1);
      |                            ~~~~~~~~~~~~~~~~~~~~~~~~~~^
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...