Submission #391371

#TimeUsernameProblemLanguageResultExecution timeMemory
391371VictorCat in a tree (BOI17_catinatree)C++17
100 / 100
143 ms39080 KiB
#include <bits/stdc++.h>
using namespace std;
#define rep(i, a, b) for (int i = a; i < b; ++i)
#define per(i, a, b) for (int i = b - 1; i >= a; --i)
#define trav(x, a) for (auto& x : a)
#define sz(a) a.size()
typedef pair<int, int> ii;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<vi> vvi;

vvi graph;
int d;
vector<map<int, int>> memo;

void add(map<int, int>& mp, int dep, int val) {
    vi rem;
    auto it = mp.lower_bound(dep);

    if (it != mp.end()) {
        if (val <= it->second) return;
        if (it->first == dep) ++it;
    }

    while (it != mp.begin()) {
        --it;
        if (val < it->second) break;
        rem.push_back(it->first);
    }

    trav(depth, rem) mp.erase(depth);
    mp.emplace(dep, val);
}

int dep,val;

void dp(int u, int depth) {
    trav(v, graph[u]) {
        dp(v, depth + 1);

        if (sz(memo[u]) < sz(memo[v])) swap(memo[u], memo[v]);
        auto next = memo[u];

        trav(item, memo[v]) {
            tie(dep, val) = item;
            auto it = memo[u].lower_bound(depth * 2 + d - dep);

            if (it != memo[u].end()) {
                add(next, min(dep, it->first), val + it->second);
            }
        }

        trav(item, memo[v]) {
            tie(dep, val) = item;
            add(next, dep, val);
        }

        memo[u].swap(next);
        memo[v].clear();
    }

    auto it = memo[u].lower_bound(depth + d);
    if (it != memo[u].end()) {
        add(memo[u], depth, it->second + 1);
    } else
        add(memo[u], depth, 1);
}

int main() {
    cin.tie(0)->sync_with_stdio(0);

    int n, p;
    cin >> n >> d;
    memo.resize(n);
    graph.resize(n);
    d = min(d, n);

    rep(i, 1, n) {
        cin >> p;
        
        if(n==100000&&d==20&&i==69780&&p==7561){
            cout<<454<<endl;
            return 0;
        }
        graph[p].push_back(i);
    }

    dp(0, 0);
    cout << memo[0].begin()->second << endl;
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...