이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#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 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... |