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

#include <algorithm>
#include <cstring>
#include <deque>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <vector>
using namespace std;
using ll = long long;
using P = pair<ll, ll>; // (v, w)
#define fst first
#define snd second

vector<P> ps;

pair<ll, bool> upper_bound(int i, ll W) {
  ll res = 0;
  bool integer = true;
  for (; i < ps.size() && W > 0; i++) {
    if (ps[i].snd > W) {
      res += __int128(ps[i].fst) * W / ps[i].snd;
      integer = false;
    } else {
      res += ps[i].fst;
    }
    W -= ps[i].snd;
  }
  return make_pair(res, integer);
}

ll best;

void dfs(int i, ll V, ll W) {
  if (W < 0)
    return;
  if (i >= ps.size()) {
    if (V > best)
      best = V;
    return;
  }
  auto ub = upper_bound(i, W);
  if (V + ub.fst <= best)
    return;
  if (ub.snd) {
    best = V + ub.fst;
    return;
  }
  dfs(i + 1, V + ps[i].fst, W - ps[i].snd);
  dfs(i + 1, V, W);
}

int main() {
  int N;
  ll W;
  while (cin >> N >> W) {
    ps.clear();
    for (int i = 0; i < N; i++) {
      ll v, w, m;
      cin >> v >> w >> m;
      for (ll k = 1; m > 0; k <<= 1) {
        ll a = min(m, k);
        if (a * w > W)
          break;
        ps.emplace_back(a * v, a * w);
        m -= a;
      }
    }
    sort(ps.begin(), ps.end(), [&](const P &a, const P &b) {
      auto x = __int128(a.fst) * b.snd;
      auto y = __int128(b.fst) * a.snd;
      if (x != y)
        return x > y;
      return a.fst > b.fst;
    });
    best = 0;
    dfs(0, 0, W);
    cout << best << endl;
  }
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <deque>
#include <functional>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <vector>
using namespace std;
using ll = long long;
using P = pair<ll, ll>; // (v, w)
#define fst first
#define snd second

vector<P> ps;

pair<ll, bool> upper_bound(int i, ll W) {
  ll res = 0;
  bool integer = true;
  for (; i < ps.size() && W > 0; i++) {
    if (ps[i].snd > W) {
      res += __int128(ps[i].fst) * W / ps[i].snd;
      integer = false;
    } else {
      res += ps[i].fst;
    }
    W -= ps[i].snd;
  }
  return make_pair(res, integer);
}

ll best = 0;

void dfs(int i, ll V, ll W) {
  if (W < 0)
    return;
  if (i >= ps.size()) {
    if (V > best)
      best = V;
    return;
  }
  auto ub = upper_bound(i, W);
  if (V + ub.fst <= best)
    return;
  if (ub.snd) {
    best = V + ub.fst;
    return;
  }
  dfs(i + 1, V + ps[i].fst, W - ps[i].snd);
  dfs(i + 1, V, W);
}

int main() {
  int N;
  ll W;
  while (~scanf("%d %lld", &N, &W)) {
    ps.clear();
    for (int i = 0; i < N; i++) {
      ll v, w, m;
      scanf("%lld %lld %lld", &v, &w, &m);
      for (ll k = 1; m > 0; k <<= 1) {
        ll a = min(m, k);
        if (a * w > W)
          break;
        ps.emplace_back(a * v, a * w);
        m -= a;
      }
    }
    sort(ps.begin(), ps.end(), [&](const P &a, const P &b) {
      return __int128(a.fst) * b.snd > __int128(b.fst) * a.snd;
    });
    best = 0;
    dfs(0, 0, W);
    printf("%lld\\n", best);
  }
  return 0;
}