제출 #102315

#제출 시각아이디문제언어결과실행 시간메모리
102315TomGautotBall Machine (BOI13_ballmachine)C++14
32.70 / 100
1084 ms21504 KiB
#include <bits/stdc++.h> #define INF 999999999 using namespace std; vector<vector<int> > treeAdj; vector<int> smallestInSubtree, freePlacesInSubtree, depth, reverseTree; int n, q; int root; int lastRolledDepth; 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; int sz = treeAdj[node].size(); for(int i = 0; i < sz; i++){ fillAllSubtree(treeAdj[node][i]); } } int addBalls(int node, int toPlace){ // returns new val after filling subtree of node if(toPlace == 0 || freePlacesInSubtree[node] <= 0) return toPlace; int freePlaces = freePlacesInSubtree[node]; if(freePlaces < toPlace){ fillAllSubtree(node); return toPlace-freePlaces; } else if(freePlaces == toPlace){ // This node is the one to be output fillAllSubtree(node); cout << node+1 << endl; return 0; } int sz = treeAdj[node].size(); //freePlacesInSubtree[node] = 0; int v, placed; for(int i = 0; i < sz && toPlace > 0; i++){ // The children are sorted by minimum id found in subtree v = treeAdj[node][i]; placed = toPlace-addBalls(v, toPlace); freePlacesInSubtree[node]-=placed; toPlace = toPlace-placed; //freePlacesInSubtree[node]+=freePlacesInSubtree[v]; } //cout << "There are now " << freePlacesInSubtree[node] << " in the subtree of " << node << endl; return toPlace; } void removeBall(int val){ int index = val; int last = index; bool addMode = false; while(true){ if(addMode){ freePlacesInSubtree[index]++; if(index == root) return; } else if(freePlacesInSubtree[index] != 0){ lastRolledDepth = depth[last]; freePlacesInSubtree[last]++; addMode = true; continue; } else if(index == root){ lastRolledDepth = depth[root]; freePlacesInSubtree[root]++; return; } last = index; index = reverseTree[index]; } } void printTreeState(){ printf("myIds: "); for(int i = 0; i < n; i++){ printf("%d ", i); } printf("\nDepth: "); for(int i = 0; i < n; i++){ printf("%d ", depth[i]); } printf("\nfpist: "); for(int i = 0; i < n; i++){ printf("%d ", freePlacesInSubtree[i]); } printf("\n"); } int main() { int p; cin >> n >> q; depth.resize(n); reverseTree.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); reverseTree[i] = p-1; } } //cout << "Going to compute data" << endl; //return 0; computeData(root, 0); //return 0; //cout << "Data was computedd successfully" << endl; int action, val; for(int i = 0; i < q; i++){ cin >> action >> val; if(action == 1){ addBalls(root, val); } else{ val--; removeBall(val); //cout << "Last rolled depth is " << *lastRolledDepth << endl; cout << depth[val] - lastRolledDepth << endl; } //printTreeState(); } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...