Problem p00777 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>
#define show(x) cerr << #x << " = " << (x) << endl
using namespace std;
template <typename T> constexpr T INF = numeric_limits<T>::max() / 16;
template <typename Functor> struct fix_type {
  Functor functor;
  template <typename... Args>
  decltype(auto) operator()(Args &&...args) const & {
    return functor(functor, std::forward<Args>(args)...);
  }
};
template <typename Functor>
fix_type<typename std::decay<Functor>::type> fix(Functor &&functor) {
  return {std::forward<Functor>(functor)};
}
struct CostGraph {
  using T = int;
  CostGraph(const int v) : V{v}, edge(v) {}
  struct Edge {
    Edge(const int from, const int to, const T cost)
        : from{from}, to{to}, cost{cost} {}
    const int from;
    const int to;
    const T cost;
    bool operator<(const Edge &e) const {
      return cost != e.cost ? cost < e.cost : to < e.to;
    }
  };
  void addEdge(const int from, const int to, const T cost) {
    edge[from].push_back(Edge{from, to, cost});
  }
  const int V;
  vector<vector<Edge>> edge;
};

template <typename Base> class SparseTable {
public:
  using T = typename Base::T;
  using SemiLattice = Base;
  SparseTable() = default;
  SparseTable(const vector<T> &val) : size(val.size()), lg2(size + 1, 0) {
    for (int i = 2; i <= size; i++) {
      lg2[i] = lg2[i / 2] + 1;
    }
    table.resize(size, vector<T>(lg2[size] + 1));
    for (int i = 0; i < size; i++) {
      table[i][0] = val[i];
    }
    for (int j = 0; j < lg2[size]; j++) {
      const int w = 1 << j;
      for (int i = 0; i <= size - (w << 1); i++) {
        T tl = table[i][j], tr = table[i + w][j];
        table[i][j + 1] = op(tl, tr);
      }
    }
  }
  void init(const vector<T> &val) {
    lg2.clear();
    table.clear();
    size = val.size(), lg2.resize(size + 1, 0);
    for (int i = 2; i <= size; i++) {
      lg2[i] = lg2[i / 2] + 1;
    }
    table.resize(size, vector<T>(lg2[size] + 1));
    for (int i = 0; i < size; i++) {
      table[i][0] = val[i];
    }
    for (int j = 0; j < lg2[size]; j++) {
      const int w = 1 << j;
      for (int i = 0; i <= size - (w << 1); i++) {
        T tl = table[i][j], tr = table[i + w][j];
        table[i][j + 1] = op(tl, tr);
      }
    }
  }
  T accumulate(const int l, const int r) const {
    assert(0 <= l and l < r and r <= size);
    const int j = lg2[r - l];
    return op(table[l][j], table[r - (1 << j)][j]);
  }

private:
  int size;
  vector<int> lg2;
  vector<vector<T>> table;
  const SemiLattice op{};
};
class LowestCommonAncestor {
public:
  // g: 有向根付き木
  LowestCommonAncestor(const CostGraph &g, const int root = 0) : left(g.V, 0) {
    vector<bool> used(g.V, false);
    auto dfs = fix([&](auto &&self, const pair<int, int> &s) -> void {
      used[s.second] = true;
      const int pos = s.second;
      left[pos] = depth.size();
      depth.push_back(s);
      for (const auto &e : g.edge[pos]) {
        if (used[e.to]) {
          continue;
        }
        self(self, {s.first + 1, e.to});
        depth.push_back(s);
      }
      st.init(depth);
    });
    dfs(make_pair(0, root));
  }
  int LCA(const int u, const int v) const {
    const int ul = left[u];
    const int vl = left[v];
    return st.accumulate(min(ul, vl), max(ul, vl) + 1).second;
  }

private:
  struct DepthMin {
    using T = pair<int, int>;
    T operator()(const T &a, const T &b) const { return min(a, b); }
  };
  vector<int> left;
  vector<pair<int, int>> depth;
  SparseTable<DepthMin> st;
};
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  while (true) {
    int N;
    cin >> N;
    if (N == 0) {
      break;
    }
    using P = pair<int, int>;
    using PP = pair<P, int>;
    vector<PP> edge(N - 1);
    vector<int> dim(N, 0);
    for (int i = 0; i < N - 1; i++) {
      edge[i].first.first = i + 1, (cin >> edge[i].first.second),
      edge[i].first.second--, dim[i + 1]++, dim[edge[i].first.second]++;
    }
    int ans = 0;
    for (int i = 0; i < N - 1; i++) {
      cin >> edge[i].second, ans += 3 * edge[i].second;
    }
    CostGraph g(N);
    for (const auto &e : edge) {
      g.addEdge(e.first.second, e.first.first, e.second);
    }
    vector<int> marked;
    for (int i = 0; i < N; i++) {
      if (dim[i] == 1 and g.edge[i].size() == 1) {
        marked.push_back(g.edge[i][0].to), ans -= 2 * g.edge[i][0].cost;
      } else {
        bool m = false;
        for (const auto &e : g.edge[i]) {
          if (dim[e.to] == 1) {
            m = true, ans -= 2 * e.cost;
          }
        }
        if (m) {
          marked.push_back(i);
        }
      }
    }
    vector<int> d(N, 0);
    auto dfs = fix([&](auto &&self, const int s, const int di) -> void {
      d[s] = di;
      for (const auto &e : g.edge[s]) {
        self(self, e.to, di + e.cost);
      }
    });
    dfs(0, 0);
    int minus = 0;
    LowestCommonAncestor lca(g);
    for (const int m1 : marked) {
      for (const int m2 : marked) {
        minus = max(minus, d[m1] + d[m2] - 2 * d[lca.LCA(m1, m2)]);
      }
    }
    cout << ans - minus << "\\n";
  }
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
template <typename T> constexpr T INF = numeric_limits<T>::max() / 16;
template <typename Functor> struct fix_type {
  Functor functor;
  template <typename... Args>
  decltype(auto) operator()(Args &&...args) const & {
    return functor(functor, std::forward<Args>(args)...);
  }
};
template <typename Functor>
fix_type<typename std::decay<Functor>::type> fix(Functor &&functor) {
  return {std::forward<Functor>(functor)};
}
struct CostGraph {
  using T = int;
  CostGraph(const int v) : V{v}, edge(v) {}
  struct Edge {
    Edge(const int from, const int to, const T cost)
        : from{from}, to{to}, cost{cost} {}
    const int from;
    const int to;
    const T cost;
    bool operator<(const Edge &e) const {
      return cost != e.cost ? cost < e.cost : to < e.to;
    }
  };
  void addEdge(const int from, const int to, const T cost) {
    edge[from].push_back(Edge{from, to, cost});
  }
  const int V;
  vector<vector<Edge>> edge;
};

template <typename Base> class SparseTable {
public:
  using T = typename Base::T;
  using SemiLattice = Base;
  SparseTable(const vector<T> &val) : size(val.size()), lg2(size + 1, 0) {
    for (int i = 2; i <= size; i++) {
      lg2[i] = lg2[i / 2] + 1;
    }
    table.resize(size, vector<T>(lg2[size] + 1));
    for (int i = 0; i < size; i++) {
      table[i][0] = val[i];
    }
    for (int j = 0; j < lg2[size]; j++) {
      const int w = 1 << j;
      for (int i = 0; i <= size - (w << 1); i++) {
        T tl = table[i][j], tr = table[i + w][j];
        table[i][j + 1] = op(tl, tr);
      }
    }
  }
  T accumulate(const int l, const int r) const {
    assert(0 <= l and l < r and r <= size);
    const int j = lg2[r - l];
    return op(table[l][j], table[r - (1 << j)][j]);
  }

private:
  const int size;
  vector<int> lg2;
  vector<vector<T>> table;
  const SemiLattice op{};
};
class LowestCommonAncestor {
public:
  // g: 有向根付き木
  LowestCommonAncestor(const CostGraph &g, const int root = 0) : left(g.V, 0) {
    vector<bool> used(g.V, false);
    auto dfs = fix([&](auto &&self, const pair<int, int> &s) -> void {
      used[s.second] = true;
      const int pos = s.second;
      left[pos] = depth.size();
      depth.push_back(s);
      for (const auto &e : g.edge[pos]) {
        if (used[e.to]) {
          continue;
        }
        self(self, {s.first + 1, e.to});
        depth.push_back(s);
      }
    });
    dfs(make_pair(0, root));
  }
  int LCA(const int u, const int v) const {
    const int ul = left[u];
    const int vl = left[v];
    return SparseTable<DepthMin>{depth}
        .accumulate(min(ul, vl), max(ul, vl) + 1)
        .second;
  }

private:
  struct DepthMin {
    using T = pair<int, int>;
    T operator()(const T &a, const T &b) const { return min(a, b); }
  };
  vector<int> left;
  vector<pair<int, int>> depth;
};
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  while (true) {
    int N;
    cin >> N;
    if (N == 0) {
      break;
    }
    using P = pair<int, int>;
    using PP = pair<P, int>;
    vector<PP> edge(N - 1);
    vector<int> dim(N, 0);
    for (int i = 0; i < N - 1; i++) {
      edge[i].first.first = i + 1, (cin >> edge[i].first.second),
      edge[i].first.second--, dim[i + 1]++, dim[edge[i].first.second]++;
    }
    int ans = 0;
    for (int i = 0; i < N - 1; i++) {
      cin >> edge[i].second, ans += 3 * edge[i].second;
    }
    CostGraph g(N);
    for (const auto &e : edge) {
      g.addEdge(e.first.second, e.first.first, e.second);
    }
    vector<int> marked;
    for (int i = 0; i < N; i++) {
      if (dim[i] == 1 and g.edge[i].size() == 1) {
        marked.push_back(g.edge[i][0].to), ans -= 2 * g.edge[i][0].cost;
      } else {
        bool m = false;
        for (const auto &e : g.edge[i]) {
          if (dim[e.to] == 1) {
            m = true, ans -= 2 * e.cost;
          }
        }
        if (m) {
          marked.push_back(i);
        }
      }
    }
    vector<int> d(N, 0);
    auto dfs = fix([&](auto &&self, const int s, const int di) -> void {
      d[s] = di;
      for (const auto &e : g.edge[s]) {
        self(self, e.to, di + e.cost);
      }
    });
    dfs(0, 0);
    int minus = 0;
    LowestCommonAncestor lca(g);
    for (const int m1 : marked) {
      for (const int m2 : marked) {
        minus = max(minus, d[m1] + d[m2] - 2 * d[lca.LCA(m1, m2)]);
      }
    }
    cout << ans - minus << "\\n";
  }
  return 0;
}