Submission #1107035

#TimeUsernameProblemLanguageResultExecution timeMemory
1107035LucaLucaMCat in a tree (BOI17_catinatree)C++17
100 / 100
383 ms27328 KiB
#include <iostream>
#include <vector>
#include <algorithm>
#include <cassert>
#warning That's not the baby, that's my baby

#define debug(x) #x << " = " << x << '\n'
using ll = long long;

const int INF = 1e9;
const int NMAX = 2e5;

std::vector<int> dp[NMAX + 1];
std::vector<int> g[NMAX + 1];
int depth[NMAX + 1];
int deepest[NMAX + 1];

int n, d;

void join(std::vector<int> &a, const std::vector<int> &b) {
  assert((int) a.size() >= (int) b.size());
  std::vector<int> c((int) b.size() + 1, 0);
  for (int mini = 0; mini < (int) c.size(); mini++) {
    if (d - 1 - mini < (int) b.size()) {
      c[mini] = std::max(c[mini], a[mini] + b[std::max(std::max(0, mini - 1), d - 1 - mini)]);
    }
    for (int j = std::max(0, mini - 1); j < (int) b.size(); j++) {
      // i + j + 1 >= d => i >= d - j - 1
      // i >= mini
      int i = std::max(d - j - 1, mini);
      if (mini <= d - j - 1 && d - j - 1 < (int) a.size()) {
        c[mini] = std::max(c[mini], a[d - j - 1] + b[j]);
      }
    }
  }
  for (int i = 0; i < (int) c.size(); i++) {
    a[i] = std::max(a[i], c[i]);
  }
}
 
void dfs(int u) {
  deepest[u] = depth[u];
  int with = -1;
  for (const auto &v : g[u]) {
    depth[v] = 1 + depth[u];
    dfs(v);
    if (deepest[v] > deepest[u]) { 
      deepest[u] = deepest[v];
      with = v;
    }
  }
  if (with == -1) { // frunza
    dp[u].resize(1);
    dp[u][0] = 1;
    return;
  }
  std::swap(dp[u], dp[with]);
  dp[u].insert(dp[u].begin(), 1);
  if ((int) dp[u].size() > d) {
    dp[u][0] += dp[u][d];
  }
  for (const auto &v : g[u]) {
    if (v != with) {
      join(dp[u], dp[v]);   
    }
  }
}

int main() {
  std::ios_base::sync_with_stdio(false);
  std::cin.tie(0);
  std::cout.tie(0);
  #ifdef LOCAL
freopen("input.txt", "r", stdin);
  #endif

  std::cin >> n >> d;
  for (int i = 1; i < n; i++) {
    int p;
    std::cin >> p;
    g[p + 1].push_back(i + 1);
  }
  dfs(1);
  std::cout << *std::max_element(dp[1].begin(), dp[1].end()) << '\n';

  return 0;
}

Compilation message (stderr)

catinatree.cpp:5:2: warning: #warning That's not the baby, that's my baby [-Wcpp]
    5 | #warning That's not the baby, that's my baby
      |  ^~~~~~~
catinatree.cpp: In function 'void join(std::vector<int>&, const std::vector<int>&)':
catinatree.cpp:30:11: warning: unused variable 'i' [-Wunused-variable]
   30 |       int i = std::max(d - j - 1, mini);
      |           ^
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...