Problem p03405 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <bitset>
#include <cassert>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

typedef long long ll;

const int N = 1e5 + 7;
const int K = 22;
const int MOD = 1e9 + 7;

int add(int a, int b) { return (a + b) % MOD; }

int mul(int a, int b) { return ((ll)a * b) % MOD; }

int binpow(int a, int b) {
  int res = 1;
  while (b) {
    if (b & 1)
      res = mul(res, a);
    a = mul(a, a);
    b >>= 1;
  }
  return res;
}

struct Dsu {
  vector<int> p;
  vector<int> rank;

  int get(int v) {
    if (p[v] != v) {
      p[v] = get(p[v]);
    }
    return p[v];
  }

  void merge(int u, int v) {
    u = get(u);
    v = get(v);
    if (u == v)
      return;
    if (rank[u] < rank[v])
      swap(u, v);
    p[v] = u;
    if (rank[u] == rank[v])
      rank[u]++;
  }

  int same(int u, int v) { return get(u) == get(v); }

  Dsu(int n) {
    p.resize(n);
    iota(p.begin(), p.end(), 0);
    rank.resize(n);
  }
};

struct Edge {
  int u, v, w;

  Edge() {}

  Edge(int u_, int v_, int w_) {
    u = u_;
    v = v_;
    w = w_;
  }

  bool operator<(const Edge &other) const { return w < other.w; }
};

int n;

int timer = 0;

int h[N];
int p[N];
int val[N];
int tin[N];
int tout[N];
int up[K][N];
int mx[K][N];
vector<pair<int, int>> g[N];

void dfs(int cur, int pr, int ch, int vl) {
  h[cur] = ch;
  p[cur] = pr;
  val[cur] = vl;
  tin[cur] = timer++;
  for (auto t : g[cur]) {
    if (t.first != p[cur]) {
      dfs(t.first, cur, ch + 1, t.second);
    }
  }
  tout[cur] = timer++;
}

void init() {
  dfs(0, -1, 0, -1);
  for (int i = 0; i < n; i++) {
    up[0][i] = p[i];
    mx[0][i] = val[i];
  }
  for (int i = 0; i + 1 < K; i++) {
    for (int j = 0; j < n; j++) {
      int mid = up[i][j];
      if (mid == -1) {
        up[i + 1][j] = -1;
      } else {
        up[i + 1][j] = up[i][mid];
        mx[i + 1][j] = max(mx[i][j], mx[i][mid]);
      }
    }
  }
}

int anc(int a, int b) { return tin[a] <= tin[b] && tout[b] <= tout[a]; }

int lca(int a, int b) {
  if (anc(a, b)) {
    return a;
  } else if (anc(b, a)) {
    return b;
  } else {
    for (int i = K - 1; i >= 0; i--) {
      if (up[i][a] != -1 && !anc(up[i][a], b)) {
        a = up[i][a];
      }
    }
    return p[a];
  }
}

int gmx(int v, int dh) {
  int ans = -1;
  for (int i = 0; i < K; i++) {
    if ((dh >> i) & 1) {
      ans = max(ans, mx[i][v]);
      v = up[i][v];
    }
  }
  return ans;
}

int mxp(int u, int v) {
  int l = lca(u, v);
  return max(gmx(u, h[u] - h[l]), gmx(v, h[v] - h[l]));
}

signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);

  int m, x;
  cin >> n >> m >> x;
  vector<Edge> ed;
  for (int i = 0; i < m; i++) {
    int u, v, w;
    cin >> u >> v >> w;
    u--;
    v--;
    ed.push_back(Edge(u, v, w));
  }
  sort(ed.begin(), ed.end());
  Dsu d(n);
  for (auto t : ed) {
    if (!d.same(t.u, t.v)) {
      d.merge(t.u, t.v);
      g[t.u].push_back({t.v, t.w});
      g[t.v].push_back({t.u, t.w});
      x -= t.w;
    }
  }
  init();
  auto gv = [&](const Edge &a) { return a.w - mxp(a.u, a.v); };
  sort(ed.begin(), ed.end(),
       [&](const Edge &a, const Edge &b) { return gv(a) < gv(b); });
  int ans = 0;
  for (int i = 1; i < m; i++) {
    if (gv(ed[i]) == x) {
      ans = add(ans, binpow(2, m - 1 - i));
    }
  }
  ans = mul(ans, 2);
  cout << ans << endl;
}


Fixed submission:
#include <algorithm>
#include <bitset>
#include <cassert>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

typedef long long ll;

#define int ll

const int N = 1e3 + 7;
const int K = 22;
const int MOD = 1e9 + 7;

int add(int a, int b) { return (a + b) % MOD; }

int mul(int a, int b) { return ((ll)a * b) % MOD; }

int binpow(int a, int b) {
  int res = 1;
  while (b) {
    if (b & 1)
      res = mul(res, a);
    a = mul(a, a);
    b >>= 1;
  }
  return res;
}

struct Dsu {
  vector<int> p;
  vector<int> rank;

  int get(int v) {
    if (p[v] != v) {
      p[v] = get(p[v]);
    }
    return p[v];
  }

  void merge(int u, int v) {
    u = get(u);
    v = get(v);
    if (u == v)
      return;
    if (rank[u] < rank[v])
      swap(u, v);
    p[v] = u;
    if (rank[u] == rank[v])
      rank[u]++;
  }

  int same(int u, int v) { return get(u) == get(v); }

  Dsu(int n) {
    p.resize(n);
    iota(p.begin(), p.end(), 0);
    rank.resize(n);
  }
};

struct Edge {
  int u, v, w;

  Edge() {}

  Edge(int u_, int v_, int w_) {
    u = u_;
    v = v_;
    w = w_;
  }

  bool operator<(const Edge &other) const { return w < other.w; }
};

int n;

int timer = 0;

int h[N];
int p[N];
int val[N];
int tin[N];
int tout[N];
int up[K][N];
int mx[K][N];
vector<pair<int, int>> g[N];

void dfs(int cur, int pr, int ch, int vl) {
  h[cur] = ch;
  p[cur] = pr;
  val[cur] = vl;
  tin[cur] = timer++;
  for (auto t : g[cur]) {
    if (t.first != p[cur]) {
      dfs(t.first, cur, ch + 1, t.second);
    }
  }
  tout[cur] = timer++;
}

void init() {
  dfs(0, -1, 0, -1);
  for (int i = 0; i < n; i++) {
    up[0][i] = p[i];
    mx[0][i] = val[i];
  }
  for (int i = 0; i + 1 < K; i++) {
    for (int j = 0; j < n; j++) {
      int mid = up[i][j];
      if (mid == -1) {
        up[i + 1][j] = -1;
      } else {
        up[i + 1][j] = up[i][mid];
        mx[i + 1][j] = max(mx[i][j], mx[i][mid]);
      }
    }
  }
}

int anc(int a, int b) { return tin[a] <= tin[b] && tout[b] <= tout[a]; }

int lca(int a, int b) {
  if (anc(a, b)) {
    return a;
  } else if (anc(b, a)) {
    return b;
  } else {
    for (int i = K - 1; i >= 0; i--) {
      if (up[i][a] != -1 && !anc(up[i][a], b)) {
        a = up[i][a];
      }
    }
    return p[a];
  }
}

int gmx(int v, int dh) {
  int ans = -1;
  for (int i = 0; i < K; i++) {
    if ((dh >> i) & 1) {
      ans = max(ans, mx[i][v]);
      v = up[i][v];
    }
  }
  return ans;
}

int mxp(int u, int v) {
  int l = lca(u, v);
  return max(gmx(u, h[u] - h[l]), gmx(v, h[v] - h[l]));
}

signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);

  int m, x;
  cin >> n >> m >> x;
  vector<Edge> ed;
  for (int i = 0; i < m; i++) {
    int u, v, w;
    cin >> u >> v >> w;
    u--;
    v--;
    ed.push_back(Edge(u, v, w));
  }
  sort(ed.begin(), ed.end());
  Dsu d(n);
  for (auto t : ed) {
    if (!d.same(t.u, t.v)) {
      d.merge(t.u, t.v);
      g[t.u].push_back({t.v, t.w});
      g[t.v].push_back({t.u, t.w});
      x -= t.w;
    }
  }
  init();
  auto gv = [&](const Edge &a) { return a.w - mxp(a.u, a.v); };
  sort(ed.begin(), ed.end(),
       [&](const Edge &a, const Edge &b) { return gv(a) < gv(b); });
  int ans = 0;
  for (int i = 1; i < m; i++) {
    if (gv(ed[i]) == x) {
      ans = add(ans, binpow(2, m - 1 - i));
    }
  }
  ans = mul(ans, 2);
  cout << ans << endl;
}