Submission #102189

#TimeUsernameProblemLanguageResultExecution timeMemory
102189TomGautotBall Machine (BOI13_ballmachine)C++14
0 / 100
222 ms42188 KiB
#include <bits/stdc++.h> #define INF 999999999 using namespace std; vector<vector<int> > treeAdj; vector<int> smallestInSubtree, freePlacesInSubtree, depth; int n, q; int root; void computeData(int node, int d){ int chld = treeAdj[node].size(); depth[node] = d; //printf("Getting data for node %d (depth %d)\n", node, d); if(chld == 0){ //printf("IT S A LEAF!\n"); smallestInSubtree[node] = node; freePlacesInSubtree[node] = 1; return; } int sml = node; int fps = 1; int v; vector<pair<int, int> > newSortedAdj; for(int i = 0; i < chld; i++){ v = treeAdj[node][i]; //printf("%d -th child of %d is %d\n", i+1, node, v); computeData(v, d+1); newSortedAdj.push_back({smallestInSubtree[v], v}); sml = min(sml, smallestInSubtree[v]); fps+= freePlacesInSubtree[v]; } sort(newSortedAdj.begin(), newSortedAdj.end()); for(int i = 0; i < chld; i++){ treeAdj[node][i] = newSortedAdj[i].second; } smallestInSubtree[node] = sml; freePlacesInSubtree[node] = fps; //printf("Got data for node %d (depth %d)\n", node, d); return; } void fillAllSubtree(int node){ if(freePlacesInSubtree[node] == 0) return; freePlacesInSubtree[node] = 0; for(int i = 0; i < treeAdj[node].size(); i++){ fillAllSubtree(treeAdj[node][i]); } } int addBalls(int node, int val){ // returns new val after filling subtree of node if(val == 0 || freePlacesInSubtree[node] <= 0) return val; int freePlaces = freePlacesInSubtree[node]; if(freePlaces < val){ fillAllSubtree(node); return val-freePlaces; } else if(freePlaces == val){ // This node is the one to be output fillAllSubtree(node); cout << node+1 << endl; return 0; } int sz = treeAdj[node].size(); for(int i = 0; i < sz && val > 0; i++){ val = addBalls(treeAdj[node][i], val); } return val; } int removeBall(int node, int val, int *lastRolledDepth){ if(node == val){ return 1; } int sz = treeAdj[node].size(); if(sz == 0){ return 0; } bool nodeIsFree = freePlacesInSubtree[node] != 0; //cout << "Is node " << node << " free " << (nodeIsFree?"1":"0") << endl; int returnCode, v; for(int i = 0; i < sz; i++){ v = treeAdj[node][i]; returnCode = removeBall(v, val, lastRolledDepth); if(returnCode == 1){ if(!nodeIsFree){ if(node == root){ freePlacesInSubtree[root]++; *lastRolledDepth = 0; return 2; } else return 1; } freePlacesInSubtree[v]++; *lastRolledDepth = depth[v]; return 2; } if(returnCode == 2) return 2; } return 0; } int main() { int p; cin >> n >> q; depth.resize(n); treeAdj.resize(n); smallestInSubtree.resize(n); freePlacesInSubtree.resize(n); for(int i = 0; i < n; i++){ cin >> p; if(p == 0) root = i; else{ treeAdj[p-1].push_back(i); } } //cout << "Going to compute data" << endl; computeData(root, 0); //cout << "Data was computedd successfully" << endl; int action, val; int *lastRolledDepth; for(int i = 0; i < q; i++){ cin >> action >> val; if(action == 1){ addBalls(root, val); } else{ val--; removeBall(root, val, lastRolledDepth); //cout << "Last rolled depth is " << *lastRolledDepth << endl; cout << depth[val] - *lastRolledDepth << endl; } } return 0; }

Compilation message (stderr)

ballmachine.cpp: In function 'void fillAllSubtree(int)':
ballmachine.cpp:54:22: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     for(int i = 0; i < treeAdj[node].size(); i++){
                    ~~^~~~~~~~~~~~~~~~~~~~~~
ballmachine.cpp: In function 'int main()':
ballmachine.cpp:140:10: warning: 'lastRolledDepth' may be used uninitialized in this function [-Wmaybe-uninitialized]
     int *lastRolledDepth;
          ^~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...