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

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <string>
#include <vector>
using namespace std;

#define PB push_back
#define MP make_pair
#define SZ(v) ((int)(v).size())
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)
#define FORE(i, a, b) for (int i = (a); i <= (b); ++i)
#define REPE(i, n) FORE(i, 0, n)
#define FORSZ(i, a, v) FOR(i, a, SZ(v))
#define REPSZ(i, v) REP(i, SZ(v))
std::mt19937
    rnd((int)std::chrono::steady_clock::now().time_since_epoch().count());
typedef long long ll;
ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); }

const int MAXN = 1 << 18;
const int MAXQ = 100000;
const int MAXLIM = 100000 * 10;

int n;
int val[MAXN], weight[MAXN];
int nq;
int qx[MAXQ], qlim[MAXQ];
ll qans[MAXQ];

int dep[MAXN];
vector<pair<int, ll>> opt[MAXN];
bool stop[MAXN];

vector<pair<int, ll>> merge(const vector<pair<int, ll>> &a,
                            const vector<pair<int, ll>> &b) {
  vector<pair<int, ll>> ret;
  int ai = 0, bi = 0;
  while (ai < SZ(a) || bi < SZ(b)) {
    pair<int, ll> cur;
    if (ai < SZ(a) &&
        (bi >= SZ(b) || a[ai].first < b[bi].first ||
         a[ai].first == b[bi].first && a[ai].second > b[bi].second))
      cur = a[ai++];
    else
      cur = b[bi++];
    if ((SZ(ret) == 0 || cur.second > ret[SZ(ret) - 1].second) &&
        cur.first <= MAXLIM)
      ret.PB(cur);
  }
  return ret;
}

vector<pair<int, ll>> calc(const vector<pair<int, ll>> &opt, int w, int v) {
  vector<pair<int, ll>> ret;
  int ai = 0, bi = 0;
  while (ai < SZ(opt) || bi < SZ(opt)) {
    pair<int, ll> cur;
    if (ai < SZ(opt) && (bi >= SZ(opt) || opt[ai].first < opt[bi].first + w ||
                         opt[ai].first == opt[bi].first + w &&
                             opt[ai].second > opt[bi].second + v))
      cur = opt[ai++];
    else
      cur = MP(opt[bi].first + w, opt[bi].second + v), ++bi;
    if ((SZ(ret) == 0 || cur.second > ret[SZ(ret) - 1].second) &&
        cur.first <= MAXLIM)
      ret.PB(cur);
  }
  return ret;
}

void solve() {
  dep[1] = 0;
  FORE(i, 2, n) dep[i] = dep[i / 2] + 1;
  int mxdep = dep[n];
  int hdep = mxdep / 2;
  FORE(i, 1, n) stop[i] = dep[i] > hdep;
  int sum = 0;
  opt[1].clear();
  opt[1].PB(MP(0, 0LL));
  opt[1].PB(MP(weight[1], (ll)val[1]));
  FORE(i, 2, n) if (!stop[i]) {
    opt[i] = calc(opt[i / 2], weight[i], val[i]);
    sum += SZ(opt[i]);
    // printf("%d: %d\\n", i, sum);
  }
  REP(qi, nq) {
    vector<pair<int, ll>> a;
    a.PB(MP(0, 0LL));
    int x = qx[qi];
    while (stop[x])
      a = calc(a, weight[x], val[x]), x /= 2;
    qans[qi] = 0;
    const vector<pair<int, ll>> &b = opt[x];
    // printf("lim:%d a: ", qlim[qi]); REPSZ(i, a) printf(" (%d:%lld)",
    // a[i].first, a[i].second); printf(" b:"); REPSZ(i, b) printf(" (%d:%lld)",
    // b[i].first, b[i].second); puts(""); if (qi % 10000 == 0) printf("%d
    // %d\\n", SZ(a), SZ(b));
    int bi = SZ(b) - 1;
    REPSZ(ai, a) {
      while (bi >= 0 && a[ai].first + b[bi].first > qlim[qi])
        --bi;
      if (bi >= 0)
        qans[qi] = max(qans[qi], a[ai].second + b[bi].second);
    }
  }
}

void run() {
  scanf("%d", &n);
  FORE(i, 1, n) scanf("%d%d", &val[i], &weight[i]);
  scanf("%d", &nq);
  REP(i, nq) scanf("%d%d", &qx[i], &qlim[i]);
  solve();
  REP(i, nq) printf("%lld\\n", qans[i]);
}

void stress() {
  REP(rep, 10) {
    n = MAXN - 1;
    val[1] = weight[1] = 1;
    FORE(i, 2, n) val[i] = weight[i] = val[i / 2] * 2;
    nq = MAXQ;
    REP(i, nq) qx[i] = rnd() % n, qlim[i] = rnd() % MAXN;
    solve();
    printf(".");
  }
}

int main() {
  run();
  // stress();
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <string>
#include <vector>
using namespace std;

#define PB push_back
#define MP make_pair
#define SZ(v) ((int)(v).size())
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define REP(i, n) FOR(i, 0, n)
#define FORE(i, a, b) for (int i = (a); i <= (b); ++i)
#define REPE(i, n) FORE(i, 0, n)
#define FORSZ(i, a, v) FOR(i, a, SZ(v))
#define REPSZ(i, v) REP(i, SZ(v))
std::mt19937
    rnd((int)std::chrono::steady_clock::now().time_since_epoch().count());
typedef long long ll;
ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); }

const int MAXN = 1 << 18;
const int MAXQ = 100000;
const int MAXLIM = 100000;

int n;
int val[MAXN], weight[MAXN];
int nq;
int qx[MAXQ], qlim[MAXQ];
ll qans[MAXQ];

int dep[MAXN];
vector<pair<int, ll>> opt[MAXN];
bool stop[MAXN];

vector<pair<int, ll>> merge(const vector<pair<int, ll>> &a,
                            const vector<pair<int, ll>> &b) {
  vector<pair<int, ll>> ret;
  int ai = 0, bi = 0;
  while (ai < SZ(a) || bi < SZ(b)) {
    pair<int, ll> cur;
    if (ai < SZ(a) &&
        (bi >= SZ(b) || a[ai].first < b[bi].first ||
         a[ai].first == b[bi].first && a[ai].second > b[bi].second))
      cur = a[ai++];
    else
      cur = b[bi++];
    if ((SZ(ret) == 0 || cur.second > ret[SZ(ret) - 1].second) &&
        cur.first <= MAXLIM)
      ret.PB(cur);
  }
  return ret;
}

void solve() {
  dep[1] = 0;
  FORE(i, 2, n) dep[i] = dep[i / 2] + 1;
  int mxdep = dep[n];
  int hdep = mxdep / 2;
  FORE(i, 1, n) stop[i] = dep[i] == 0 || dep[i] == hdep;
  FORE(i, 1, n) {
    opt[i].clear();
    if (stop[i]) {
      opt[i].PB(MP(0, 0LL));
      opt[i].PB(MP(weight[i], (ll)val[i]));
    } else {
      vector<pair<int, ll>> nopt;
      int par = i / 2;
      REPSZ(j, opt[par])
      nopt.PB(MP(opt[par][j].first + weight[i], opt[par][j].second + val[i]));
      opt[i] = merge(opt[par], nopt);
    }
  }
  REP(qi, nq) {
    vector<int> stops;
    stops.PB(qx[qi]);
    for (int x = qx[qi]; x >= 1; x /= 2)
      if (stop[x] && x / 2 >= 1)
        stops.PB(x / 2);
    assert(SZ(stops) <= 2 && SZ(stops) >= 1);
    qans[qi] = 0;
    // printf("stops:"); REPSZ(i, stops) printf(" %d", stops[i]); puts("");
    if (SZ(stops) == 1) {
      const vector<pair<int, ll>> &a = opt[stops[0]];
      REPSZ(i, a)
      if (a[i].first <= qlim[qi]) qans[qi] = max(qans[qi], a[i].second);
      // printf("lim:%d a: ", qlim[qi]); REPSZ(i, a) printf(" (%d/%lld)",
      // a[i].first, a[i].second); puts("");
    } else {
      const vector<pair<int, ll>> &a = opt[stops[0]];
      const vector<pair<int, ll>> &b = opt[stops[1]];
      // printf("lim:%d a: ", qlim[qi]); REPSZ(i, a) printf(" (%d/%lld)",
      // a[i].first, a[i].second); printf(" b:"); REPSZ(i, b) printf("
      // (%d,%lld)", b[i].first, b[i].second); puts("");
      int bi = SZ(b) - 1;
      REPSZ(ai, a) {
        while (bi >= 0 && a[ai].first + b[bi].first > qlim[qi])
          --bi;
        if (bi >= 0)
          qans[qi] = max(qans[qi], a[ai].second + b[bi].second);
      }
    }
  }
}

void run() {
  scanf("%d", &n);
  FORE(i, 1, n) scanf("%d%d", &val[i], &weight[i]);
  scanf("%d", &nq);
  REP(i, nq) scanf("%d%d", &qx[i], &qlim[i]);
  solve();
  REP(i, nq) printf("%lld\\n", qans[i]);
}

int main() {
  run();
  return 0;
}