Submission #518289

#TimeUsernameProblemLanguageResultExecution timeMemory
518289athensclubBall Machine (BOI13_ballmachine)C++14
62.00 / 100
388 ms26044 KiB
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <queue>
using namespace std;

int findMinSubtree(int node, vector<int> children[], int minSubtree[])
{
    if (minSubtree[node] > 0)
        return minSubtree[node];

    int temp = node;
    for (int child : children[node])
        temp = min(temp, findMinSubtree(child, children, minSubtree));

    minSubtree[node] = temp;
    return temp;
}

void visitOrdered(int node, vector<int> children[], vector<int> &order)
{
    for (int child : children[node])
        visitOrdered(child, children, order);

    order.push_back(node);
}

void findUp(int node, vector<int> children[], int parent[], vector<vector<int>> &up, int logN, int depth[])
{
    up[node][0] = parent[node] == 0 ? node : parent[node];
    for (int i = 1; i <= logN; i++)
        up[node][i] = up[up[node][i - 1]][i - 1];

    for (int child : children[node])
    {
        depth[child] = depth[node] + 1;
        findUp(child, children, parent, up, logN, depth);
    }
}

int main()
{
    int n, q;
    cin >> n >> q;

    int parent[n + 5];
    int minSubtree[n + 5];
    bool hasBall[n + 5];
    vector<int> children[n + 5];
    int root;
    for (int i = 1; i <= n; i++)
    {
        hasBall[i] = false;
        minSubtree[i] = 0;
        cin >> parent[i];
        if (parent[i] == 0)
            root = i;
        else
            children[parent[i]].push_back(i);
    }

    findMinSubtree(root, children, minSubtree);
    for (int i = 1; i <= n; i++)
    {
        sort(children[i].begin(), children[i].end(), [&minSubtree](const int node1, const int node2)
             { return minSubtree[node1] < minSubtree[node2]; });
    }

    int logN = (int)ceil(log2(n));
    int depth[n + 5];
    depth[root] = 0;
    vector<vector<int>> up(n + 5, vector<int>(logN + 1));
    findUp(root, children, parent, up, logN, depth);

    vector<int> order;
    visitOrdered(root, children, order);

    for (int i = 0; i < q; i++)
    {
        int t, k;
        cin >> t >> k;
        if (t == 1)
        {
            for (int j = 0; j < k; j++)
                hasBall[order[j]] = true;
            cout << order[k-1] << endl;
        }
        else
        {
            int temp = logN;
            int tempNode = k;
            int target = k;
            while (temp >= 0 && target != root)
            {
                if (hasBall[up[tempNode][temp]])
                {
                //cout << temp << " " << tempNode << endl;
                    target = up[tempNode][temp];
                    tempNode = up[tempNode][temp];
                }
                else
                {
                    temp--;
                }
            }
            hasBall[target] = false;
            cout << (depth[k] - depth[target]) << endl;
        }
    }
}

Compilation message (stderr)

ballmachine.cpp: In function 'int main()':
ballmachine.cpp:94:40: warning: 'root' may be used uninitialized in this function [-Wmaybe-uninitialized]
   94 |             while (temp >= 0 && target != root)
      |                                 ~~~~~~~^~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...