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

#include <iostream>
#include <stdio.h>
#include <vector>
using namespace std;
typedef long long ll;

vector<pair<int, ll>> path[100005];
int par[100005];
int dep[100005];
int siz[100005];
ll cst[100005];
int hev[100005];
void dfs(int a) {
  siz[a] = 1;
  for (int i = 0; i < path[a].size(); i++) {
    int d = path[a][i].first;
    if (d == par[a])
      continue;
    par[d] = a;
    dep[d] = dep[a] + 1;
    cst[d] = path[a][i].second;
    dfs(d);
    siz[a] += siz[d];
    if (!hev[a] || siz[hev[a]] < siz[d])
      hev[a] = d;
  }
}

ll k;
ll add[100005];
ll edgecost(int a) {
  ll ret = add[a] + add[par[a]] + cst[a];
  return ret % k ? ret : 0;
}

int pos[100005];
int hl_par[100005];

ll bit[100005];
ll sum(int i) {
  ll ret = 0;
  while (i) {
    ret += bit[i];
    i -= i & -i;
  }
  return ret;
}
void set(int i, ll x) {
  // printf("set %d %lld\\n", i, x);
  x -= sum(i + 1) - sum(i);
  i++;
  while (i < 100005) {
    bit[i] += x;
    i += i & -i;
  }
}

int lca(int a, int b) {
  int p = hl_par[a], q = hl_par[b];
  if (p == q)
    return dep[a] < dep[b] ? a : b;
  if (dep[p] < dep[q])
    return lca(a, par[q]);
  else
    return lca(par[p], b);
}
ll cost(int a) {
  ll ret = 0;
  while (a) {
    int p = hl_par[a];
    ret += sum(pos[a]) - sum(pos[p]);
    if (p)
      ret += edgecost(p);
    // printf("%d->%d:%lld %d->%d:%lld\\n", a, p, sum(pos[a])-sum(pos[p]), p,
    // par[p], edgecost(p));
    a = par[p];
  }
  return ret;
}

int main() {
  int n;
  cin >> n >> k;
  for (int i = 0; i < n - 1; i++) {
    int a, b;
    ll c;
    cin >> a >> b >> c;
    path[a].push_back(make_pair(b, c));
    path[b].push_back(make_pair(a, c));
  }
  for (int i = 0; i < n; i++)
    hev[i] = 0;
  par[0] = dep[0] = cst[0] = 0;
  dfs(0);

  for (int i = 0; i < n; i++)
    add[i] = 0;

  int cnt = 0;
  for (int i = 0; i < n; i++)
    pos[i] = -1;
  for (int i = 0; i < n; i++) {
    if (i && hev[par[i]] == i)
      continue;
    int j = i;
    do {
      // printf("%d ", j);
      pos[j] = cnt++;
      hl_par[j] = i;
    } while (j = hev[j]);
  }
  // printf("\\n");

  for (int i = 0; i < 100005; i++)
    bit[i] = 0;
  for (int i = 0; i < n; i++)
    set(pos[i], edgecost(hev[i]));

  int q;
  cin >> q;
  for (int i = 0; i < q; i++) {
    string s;
    ll a, b;
    cin >> s >> a >> b;
    if (s[0] == 'a') {
      add[a] += b;
      // for(int i=0; i<10; i++) printf("%lld ", sum(i)); printf("\\n");
      set(pos[a], edgecost(hev[a]));
      if (a)
        set(pos[a] - 1, edgecost(a));
      // for(int i=0; i<10; i++) printf("%lld ", sum(i)); printf("\\n");
    } else {
      cout << (cost(a) + cost(b) - 2 * cost(lca(a, b))) << endl;
    }
  }
}

Error: TLE

Fixed submission:

#include <iostream>
#include <vector>
using namespace std;
typedef long long ll;

vector<pair<int, ll>> path[100005];
int par[100005];
int dep[100005];
int siz[100005];
ll cst[100005];
int hev[100005];
void dfs(int a) {
  siz[a] = 1;
  for (int i = 0; i < path[a].size(); i++) {
    int d = path[a][i].first;
    if (d == par[a])
      continue;
    par[d] = a;
    dep[d] = dep[a] + 1;
    cst[d] = path[a][i].second;
    dfs(d);
    siz[a] += siz[d];
    if (!hev[a] || siz[hev[a]] < siz[d])
      hev[a] = d;
  }
}

ll k;
ll add[100005];
ll edgecost(int a) {
  ll ret = add[a] + add[par[a]] + cst[a];
  return ret % k ? ret : 0;
}

int pos[100005];
int hl_par[100005];

ll bit[100005];
ll sum(int i) {
  ll ret = 0;
  while (i) {
    ret += bit[i];
    i -= i & -i;
  }
  return ret;
}
void set(int i, ll x) {
  x -= sum(i + 1) - sum(i);
  i++;
  while (i < 100005) {
    bit[i] += x;
    i += i & -i;
  }
}

int lca(int a, int b) {
  int p = hl_par[a], q = hl_par[b];
  if (p == q)
    return dep[a] < dep[b] ? a : b;
  if (dep[p] < dep[q])
    return lca(par[p], b);
  else
    return lca(a, par[q]);
}
ll cost(int a) {
  ll ret = 0;
  while (a) {
    int p = hl_par[a];
    ret += sum(a) - sum(p);
    ret += edgecost(p);
    a = p;
  }
  return ret;
}

int main() {
  int n;
  cin >> n >> k;
  for (int i = 0; i < n - 1; i++) {
    int a, b;
    ll c;
    cin >> a >> b >> c;
    path[a].push_back(make_pair(b, c));
    path[b].push_back(make_pair(a, c));
  }
  for (int i = 0; i < n; i++)
    hev[i] = 0;
  par[0] = dep[0] = cst[0] = 0;
  dfs(0);

  for (int i = 0; i < n; i++)
    add[i] = 0;

  int cnt = 0;
  for (int i = 0; i < n; i++)
    pos[i] = -1;
  for (int i = 0; i < n; i++) {
    if (pos[i] != -1)
      continue;
    int j = i;
    do {
      pos[j] = cnt++;
      hl_par[j] = i;
    } while (j = hev[j]);
  }

  for (int i = 0; i < 100005; i++)
    bit[i] = 0;

  int q;
  cin >> q;
  for (int i = 0; i < q; i++) {
    string s;
    ll a, b;
    cin >> s >> a >> b;
    if (s[0] == 'a') {
      add[a] += b;
      set(pos[a], edgecost(hev[a]));
      if (a)
        set(pos[a] - 1, edgecost(a));
    } else {
      cout << cost(a) + cost(b) - cost(lca(a, b)) << endl;
    }
  }
}