Language: C++

#include<bits/stdc++.h>

using namespace std;

using int64 = long long;
const int INF = 1 << 30;

struct edge
{
  int to;
  int64 cost;

  pair< int, int > to_adjust, curr_adjust;
};

int N, K, Q;
char S[500][10];
int A[500], B[500];
vector< vector< edge > > g;
int64 weight[100000];

struct TreeContraction
{
  vector< int > marker, order, parent;
  edge NONE;

  TreeContraction(int n)
  {
    g.resize(n);
    destroy();
    NONE = (edge) {-1};
  }

  void destroy()
  {
    marker.assign(g.size(), 0);
  }

  void add_edge(int idx, const edge &e)
  {
    g[idx].emplace_back(e);
  }

  void build()
  {
    function< void(int, int) > dfs = [&](int idx, int par)
    {
      for(auto &e : g[idx]) {
        if(e.to == par) continue;
        dfs(e.to, idx);
      }
      parent[idx] = par;
      order.emplace_back(idx);
    };
    parent.resize(g.size());
    dfs(0, -1);
    order.pop_back();
  }

  inline void mark(int x)
  {
    marker[x] = 2;
  }

  void contract(vector< vector< edge > > &gg)
  {
    for(int i : order) {
      if(marker[i] >= 1) ++marker[parent[i]];
    }
    gg.assign(g.size(), vector< edge >());
    inline function< edge(int, int) > contraction = [&](int idx, int par)
    {
      vector< pair< edge, edge > > reach;
      for(auto &e : g[idx]) {
        if(e.to == par) continue;
        auto ret = contraction(e.to, idx);
        if(~ret.to) {
          reach.emplace_back(ret, e);
          reach.back().first.cost += e.cost;
          if(reach.back().first.to_adjust.first == -1) {
            reach.back().first.to_adjust = {idx, e.cost};
          } else if(marker[idx] <= 1) { // to-to_adjust * - -!idx
            auto sum = e.cost + weight[e.to] + weight[idx];
            if(sum % K == 0) reach.back().first.cost -= sum; // えーわからない
          }
        }
      }
      if(marker[idx] >= 2) {
        for(auto &e : reach) {
          gg[idx].emplace_back((edge) {e.first.to, e.first.cost, e.first.to_adjust, make_pair(e.second.to, e.second.cost)});
          gg[e.first.to].emplace_back((edge) {idx, e.first.cost, make_pair(e.second.to, e.second.cost), e.first.to_adjust});
        }
        return ((edge) {idx, 0, make_pair(-1, -1), make_pair(-1, -1)});
      } else if(reach.empty()) {
        return (NONE);
      } else if(reach.size() == 1) {
        reach[0].first.cost += weight[idx];
        reach[0].first.cost += weight[idx];
        return (reach[0].first);
      } else {
        assert(false);
      }
    };
    contraction(0, -1);
  }
};


int main()
{


  scanf("%d %d", &N, &K);
  TreeContraction tree(N);
  for(int i = 1; i < N; i++) {
    int a, b, c;
    scanf("%d %d %d", &a, &b, &c);
    tree.add_edge(a, (edge) {b, c});
    tree.add_edge(b, (edge) {a, c});
  }
  tree.build();
  scanf("%d", &Q);

  int64 cost;
  vector< vector< edge > > gg;

  function< bool(int, int, int) > dfs2 = [&](int s, int t, int par)
  {
    if(s == t) {
      cost += weight[t];
      cost += weight[t];
      return (true);
    }
    for(auto &e : gg[s]) {
      if(e.to == par) continue;
      if(dfs2(e.to, t, s)) {
        auto sum = weight[s] + weight[e.curr_adjust.first] + e.curr_adjust.second;
        if(sum % K == 0) cost -= sum;
        if(e.to_adjust.first != s) {
          sum = weight[e.to] + weight[e.to_adjust.first] + e.to_adjust.second;
          if(sum % K == 0) cost -= sum;
        }
        cost += e.cost;
        cost += weight[s];
        cost += weight[s];
        return (true);
      }
    }
    return (false);
  };


  for(int i = 0; i < Q; i += 375) {
    int l = i, r = min(i + 375, Q);
    tree.destroy();
    for(int j = 0; j < r - l; j++) {
      scanf(" %s %d %d", S[j], &A[j], &B[j]);
      if(S[j][0] == 'a') tree.mark(A[j]);
      else tree.mark(A[j]), tree.mark(B[j]);
    }
    tree.contract(gg);
    for(int j = 0; j < r - l; j++) {
      if(S[j][0] == 'a') {
        weight[A[j]] += B[j];
      } else {
        cost = 0;
        dfs2(B[j], A[j], -1);
        printf("%lld\n", cost - weight[A[j]] - weight[B[j]]);
      }
    }
  }
}



Compiler output:
a.cc: In member function 'void TreeContraction::contract(std::vector<std::vector<edge> >&)':
a.cc:71:5: error: 'inline' specifier invalid for variable 'contraction' declared at block scope
   71 |     inline function< edge(int, int) > contraction = [&](int idx, int par)
      |     ^~~~~~