Problem p00362 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;

const int inf = 1001001001;

struct e {
  int to, cost;
  e(int to, int cost) : to(to), cost(cost) {}
};

struct edge {
  int to;
  bool edge_type;
  long long cost, scost, tcost;

  edge() {}
  // edge(int to, long long cost) : to(to), cost(cost) {}
  edge(int to, long long cost, bool edge_type, long long scost, long long tcost)
      : to(to), cost(cost), edge_type(edge_type), scost(scost), tcost(tcost) {}
};

struct query {
  bool type; // := add is true, send is false. kore eigo attennnoka
  int a, b;
  query() {}
  query(char s, int a, int b) : a(a), b(b) { type = (s == 'a'); }
};

int n, k, cnt;
vector<e> G[101010];
vector<edge> minG[101010];
query Q[1000];
int depth[101010], euler_tour[202020];
long long add[101010];
bool used[101010];

long long sqrt_int(long long n) {
  long long l = 1, r = n;
  while (r - l > 1) {
    long long m = (l + r) / 2;
    if (m * m <= n)
      l = m;
    else
      r = m;
  }
  return l;
}

void dfs(int v = 0, int p = -1, int d = 0) {
  // euler_tour.push_back(v);
  euler_tour[cnt++] = v;
  depth[v] = d;
  for (auto u : G[v]) {
    if (u.to == p)
      continue;
    dfs(u.to, v, d + 1);
    // euler_tour.push_back(v);
    euler_tour[cnt++] = v;
  }
}

inline void dfs2(int v, int from, int p = -1, long long cost = 0, int cnt = 0,
                 int scost = -1, int tcost = -1) {
  // cerr << v << " ( <- " << from << " )" << endl;
  if (cnt == 0) {
    for (auto u : G[v]) {
      if (u.to == p)
        continue;
      dfs2(u.to, from, v, 0, cnt + 1, u.cost + add[u.to], u.cost + add[v]);
    }
  } else if (used[v]) {

    if (cnt == 1) {
      minG[v].push_back(edge(from, scost - add[v], true, -1, -1));
      minG[from].push_back(edge(v, scost - add[v], true, -1, -1));
    } else {
      minG[v].push_back(edge(from, cost, false, tcost, scost));
      minG[from].push_back(edge(v, cost, false, scost, tcost));
    }

    dfs2(v, v, p, 0, 0, -1, -1);
  } else {
    for (auto u : G[v]) {
      if (u.to == p)
        continue;

      long long edge_cost = add[v] + add[u.to] + u.cost;
      if (used[u.to] || edge_cost % k == 0)
        edge_cost = 0;
      dfs2(u.to, from, v, cost + edge_cost, cnt + 1, scost, u.cost + add[v]);
    }
  }
}

inline bool dfs3(int s, int to, int p = -1, long long cost = 0) {
  if (s == to) {
    printf("%d\n", cost);
    // cout << cost << endl;
    return true;
  }

  for (auto u : minG[s]) {
    int t = u.to;
    if (t == p)
      continue;

    if (u.edge_type) {
      long long edge_cost = u.cost + add[s] + add[t];
      if (edge_cost % k == 0)
        edge_cost = 0;
      if (dfs3(t, to, s, cost + edge_cost))
        return true;
    } else {
      long long scost = u.scost + add[s], tcost = u.tcost + add[t];
      if (scost % k == 0)
        scost = 0;
      if (tcost % k == 0)
        tcost = 0;
      if (dfs3(t, to, s, cost + u.cost + scost + tcost))
        return true;
    }
  }
  return false;
}

void debug() {
  cout << "minimum graph" << endl;
  for (int v = 0; v < n; ++v) {
    for (auto u : minG[v])
      cout << v << " -> " << u.to << " edge_type : " << u.edge_type << " "
           << u.scost << " + " << u.cost << " + " << u.tcost << endl;
  }
}

int main() {
  scanf("%d %d", &n, &k);
  // cin >> n >> k;

  // G.resize(n);

  for (int i = 0; i < n - 1; ++i) {
    int u, v, c;
    scanf("%d %d %d", &u, &v, &c);
    // cin >> u >> v >> c;

    G[u].push_back(e(v, c));
    G[v].push_back(e(u, c));
  }

  dfs();

  int q;
  scanf("%d", &q);
  // cin >> q;

  int root_q = sqrt_int(q);
  // int root_q = 300;
  int r = (q + root_q - 1) / root_q;
  for (int p = 0; p < r; ++p) {
    int rr = min(root_q, q - p * root_q);
    // vector<query> Q;
    memset(used, false, sizeof(used));
    // minG.assign(n, vector<edge>());
    for (int i = 0; i < n; ++i)
      minG[i].clear();

    for (int i = 0; i < rr; ++i) {
      // string s;
      char s[10];
      int a, b;
      scanf("%s %d %d", s, &a, &b);
      // cin >> s >> a >> b;
      Q[i] = query(s[0], a, b);

      if (Q[i].type) {
        used[a] = true;
      } else {
        used[a] = used[b] = true;
      }
    }

    pair<int, int> mini, root;
    mini = root = make_pair(inf, -1);
    for (int i = 0; i < cnt; ++i) {
      int v = euler_tour[i];
      mini = min(mini, make_pair(depth[v], v));
      if (used[v]) {
        if (mini.second != -1)
          used[mini.second] = true;
        mini = make_pair(depth[v], v);
        root = min(root, make_pair(depth[v], v));
      }
    }

    dfs2(root.second, root.second);
    // debug();

    for (int i = 0; i < rr; ++i) {
      if (Q[i].type) {
        add[Q[i].a] += Q[i].b;
      } else {
        dfs3(Q[i].a, Q[i].b);
      }
    }
  }
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;

const int inf = 1001001001;

struct e {
  int to, cost;
  e(int to, int cost) : to(to), cost(cost) {}
};

struct edge {
  int to;
  bool edge_type;
  long long cost, scost, tcost;

  edge() {}
  // edge(int to, long long cost) : to(to), cost(cost) {}
  edge(int to, long long cost, bool edge_type, long long scost, long long tcost)
      : to(to), cost(cost), edge_type(edge_type), scost(scost), tcost(tcost) {}
};

struct query {
  bool type; // := add is true, send is false. kore eigo attennnoka
  int a, b;
  query() {}
  query(char s, int a, int b) : a(a), b(b) { type = (s == 'a'); }
};

int n, k, cnt;
vector<e> G[101010];
vector<edge> minG[101010];
query Q[1000];
int depth[101010], euler_tour[202020];
long long add[101010];
bool used[101010];

long long sqrt_int(long long n) {
  long long l = 1, r = n;
  while (r - l > 1) {
    long long m = (l + r) / 2;
    if (m * m <= n)
      l = m;
    else
      r = m;
  }
  return l;
}

inline void dfs(int v = 0, int p = -1, int d = 0) {
  // euler_tour.push_back(v);
  euler_tour[cnt++] = v;
  depth[v] = d;
  for (auto u : G[v]) {
    if (u.to == p)
      continue;
    dfs(u.to, v, d + 1);
    // euler_tour.push_back(v);
    euler_tour[cnt++] = v;
  }
}

inline void dfs2(int v, int from, int p = -1, long long cost = 0, int cnt = 0,
                 int scost = -1, int tcost = -1) {
  // cerr << v << " ( <- " << from << " )" << endl;
  if (cnt == 0) {
    for (auto u : G[v]) {
      if (u.to == p)
        continue;
      dfs2(u.to, from, v, 0, cnt + 1, u.cost + add[u.to], u.cost + add[v]);
    }
  } else if (used[v]) {

    if (cnt == 1) {
      minG[v].push_back(edge(from, scost - add[v], true, -1, -1));
      minG[from].push_back(edge(v, scost - add[v], true, -1, -1));
    } else {
      minG[v].push_back(edge(from, cost, false, tcost, scost));
      minG[from].push_back(edge(v, cost, false, scost, tcost));
    }

    dfs2(v, v, p, 0, 0, -1, -1);
  } else {
    for (auto u : G[v]) {
      if (u.to == p)
        continue;

      long long edge_cost = add[v] + add[u.to] + u.cost;
      if (used[u.to] || edge_cost % k == 0)
        edge_cost = 0;
      dfs2(u.to, from, v, cost + edge_cost, cnt + 1, scost, u.cost + add[v]);
    }
  }
}

inline bool dfs3(int s, int to, int p = -1, long long cost = 0) {
  if (s == to) {
    printf("%d\n", cost);
    // cout << cost << endl;
    return true;
  }

  for (auto u : minG[s]) {
    int t = u.to;
    if (t == p)
      continue;

    if (u.edge_type) {
      long long edge_cost = u.cost + add[s] + add[t];
      if (edge_cost % k == 0)
        edge_cost = 0;
      if (dfs3(t, to, s, cost + edge_cost))
        return true;
    } else {
      long long scost = u.scost + add[s], tcost = u.tcost + add[t];
      if (scost % k == 0)
        scost = 0;
      if (tcost % k == 0)
        tcost = 0;
      if (dfs3(t, to, s, cost + u.cost + scost + tcost))
        return true;
    }
  }
  return false;
}

void debug() {
  cout << "minimum graph" << endl;
  for (int v = 0; v < n; ++v) {
    for (auto u : minG[v])
      cout << v << " -> " << u.to << " edge_type : " << u.edge_type << " "
           << u.scost << " + " << u.cost << " + " << u.tcost << endl;
  }
}

int main() {
  scanf("%d %d", &n, &k);
  // cin >> n >> k;

  // G.resize(n);

  for (int i = 0; i < n - 1; ++i) {
    int u, v, c;
    scanf("%d %d %d", &u, &v, &c);
    // cin >> u >> v >> c;

    G[u].push_back(e(v, c));
    G[v].push_back(e(u, c));
  }

  dfs();

  int q;
  scanf("%d", &q);
  // cin >> q;

  int root_q = sqrt_int(q);
  // int root_q = 300;
  int r = (q + root_q - 1) / root_q;
  for (int p = 0; p < r; ++p) {
    int rr = min(root_q, q - p * root_q);
    // vector<query> Q;
    memset(used, false, sizeof(used));
    // minG.assign(n, vector<edge>());
    for (int i = 0; i < n; ++i)
      minG[i].clear();

    for (int i = 0; i < rr; ++i) {
      // string s;
      char s[10];
      int a, b;
      scanf("%s %d %d", s, &a, &b);
      // cin >> s >> a >> b;
      Q[i] = query(s[0], a, b);

      if (Q[i].type) {
        used[a] = true;
      } else {
        used[a] = used[b] = true;
      }
    }

    pair<int, int> mini, root;
    mini = root = make_pair(inf, -1);
    for (int i = 0; i < cnt; ++i) {
      int v = euler_tour[i];
      mini = min(mini, make_pair(depth[v], v));
      if (used[v]) {
        if (mini.second != -1)
          used[mini.second] = true;
        mini = make_pair(depth[v], v);
        root = min(root, make_pair(depth[v], v));
      }
    }

    dfs2(root.second, root.second);
    // debug();

    for (int i = 0; i < rr; ++i) {
      if (Q[i].type) {
        add[Q[i].a] += Q[i].b;
      } else {
        dfs3(Q[i].a, Q[i].b);
      }
    }
  }
}