Problem p02648 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
#define reg register
typedef long long ll;
using namespace std;
namespace IO {
char buf[1 << 15], *S, *T;
inline char gc() {
  if (S == T) {
    T = (S = buf) + fread(buf, 1, 1 << 15, stdin);
    if (S == T)
      return EOF;
  }
  return *S++;
}
inline int read() {
  reg int x;
  reg char c;
  for (; (c = gc()) < '0' || c > '9';)
    ;
  for (x = c ^ '0'; (c = gc()) >= '0' && c <= '9'; x = x * 10 + c - '0')
    ;
  return x;
}
const int _outlim = 1 << 20;
char outbuf[_outlim + 5];
int cnt;
inline void pc(char c) {
  outbuf[cnt++] = c;
  if (cnt == _outlim)
    fwrite(outbuf, 1, cnt, stdout), cnt = 0;
}
inline void write(int x) {
  if (x > 9)
    write(x / 10);
  pc(x % 10 ^ '0');
}
inline void end() {
  if (cnt)
    fwrite(outbuf, 1, cnt, stdout);
  fclose(stdin);
  fclose(stdout);
}
} // namespace IO
using IO::pc;
using IO::read;
using IO::write;
const int MN = 2 << 18 | 5;
const int MM = 65;
int n, m, V[MN], W[MN], v[25], w[25];
int f1[MM], f2[MM], f3[MM], g1[MM], g2[MM], g3[MM], id1[MM], id2[MM], id3[MM];
int main() {
  freopen("t.in", "r", stdin);
  freopen("t.out", "w", stdout);
  n = read();
  for (reg int i = 1; i <= n; i++)
    V[i] = read(), W[i] = read();
  m = read();
  while (m--) {
    static int x, y, tot, lmid, rmid, cnt1, cnt2, cnt3, i, j, k, U, res, cost,
        Ans;
    x = read();
    y = read();
    tot = 0;
    while (x) {
      if (W[x] <= y)
        v[++tot] = V[x], w[tot] = W[x];
      x /= 2;
    }
    lmid = tot / 3, rmid = tot * 2 / 3, cnt1 = cnt2 = cnt3 = 0;
    for (i = 0, U = 1 << lmid; i < U; i++) {
      res = 0, cost = 0;
      for (j = 1; cost <= y && j <= lmid; j++)
        if ((i >> (j - 1)) & 1)
          res += v[j], cost += w[j];
      if (cost <= y)
        f1[++cnt1] = res, g1[cnt1] = cost;
    }
    for (i = 0, U = 1 << (rmid - lmid); i < U; i++) {
      res = 0, cost = 0;
      for (j = lmid + 1; cost <= y && j <= rmid; j++)
        if ((i >> (j - lmid - 1)) & 1)
          res += v[j], cost += w[j];
      if (cost <= y)
        f2[++cnt2] = res, g2[cnt2] = cost;
    }
    for (i = 0, U = 1 << (tot - rmid); i < U; i++) {
      res = 0, cost = 0;
      for (j = rmid + 1; cost <= y && j <= tot; j++)
        if ((i >> (j - rmid - 1)) & 1)
          res += v[j], cost += w[j];
      if (cost <= y)
        f3[++cnt3] = res, g3[cnt3] = cost;
    }
    for (i = 1; i <= cnt1; i++)
      id1[i] = i;
    for (i = 1; i <= cnt2; i++)
      id2[i] = i;
    for (i = 1; i <= cnt3; i++)
      id3[i] = i;
    sort(id1 + 1, id1 + 1 + cnt1, [](int a, int b) { return g1[a] < g1[b]; });
    sort(id2 + 1, id2 + 1 + cnt2, [](int a, int b) { return g2[a] < g2[b]; });
    sort(id3 + 1, id3 + 1 + cnt3, [](int a, int b) { return g3[a] < g3[b]; });
    Ans = 0;
    for (i = 1; i <= cnt3; i++)
      f3[id3[i]] = max(f3[id3[i]], f3[id3[i - 1]]);
    for (i = 1; i <= cnt1; i++)
      for (j = 1, k = cnt3; j <= cnt2; j++) {
        while (k && g1[id1[i]] + g2[id2[j]] + g3[id3[k]] > y)
          k--;
        if (!k)
          break;
        Ans = max(Ans, f1[id1[i]] + f2[id2[j]] + f3[id3[k]]);
      }
    write(Ans);
    pc('\n');
  }
  IO::end();
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
#define reg register
typedef long long ll;
using namespace std;
namespace IO {
char buf[1 << 15], *S, *T;
inline char gc() {
  if (S == T) {
    T = (S = buf) + fread(buf, 1, 1 << 15, stdin);
    if (S == T)
      return EOF;
  }
  return *S++;
}
inline int read() {
  reg int x;
  reg char c;
  for (; (c = gc()) < '0' || c > '9';)
    ;
  for (x = c ^ '0'; (c = gc()) >= '0' && c <= '9'; x = x * 10 + c - '0')
    ;
  return x;
}
const int _outlim = 1 << 20;
char outbuf[_outlim + 5];
int cnt;
inline void pc(char c) {
  outbuf[cnt++] = c;
  if (cnt == _outlim)
    fwrite(outbuf, 1, cnt, stdout), cnt = 0;
}
inline void write(int x) {
  if (x > 9)
    write(x / 10);
  pc(x % 10 ^ '0');
}
inline void end() {
  if (cnt)
    fwrite(outbuf, 1, cnt, stdout);
  fclose(stdin);
  fclose(stdout);
}
} // namespace IO
using IO::pc;
using IO::read;
using IO::write;
const int MN = 2 << 18 | 5;
const int MM = 65;
int n, m, V[MN], W[MN], v[25], w[25];
int f1[MM], f2[MM], f3[MM], g1[MM], g2[MM], g3[MM], id1[MM], id2[MM], id3[MM];
int main() {
  n = read();
  for (reg int i = 1; i <= n; i++)
    V[i] = read(), W[i] = read();
  m = read();
  while (m--) {
    static int x, y, tot, lmid, rmid, cnt1, cnt2, cnt3, i, j, k, U, res, cost,
        Ans;
    x = read();
    y = read();
    tot = 0;
    while (x) {
      if (W[x] <= y)
        v[++tot] = V[x], w[tot] = W[x];
      x /= 2;
    }
    lmid = tot / 3, rmid = tot * 2 / 3, cnt1 = cnt2 = cnt3 = 0;
    for (i = 0, U = 1 << lmid; i < U; i++) {
      res = 0, cost = 0;
      for (j = 1; cost <= y && j <= lmid; j++)
        if ((i >> (j - 1)) & 1)
          res += v[j], cost += w[j];
      if (cost <= y)
        f1[++cnt1] = res, g1[cnt1] = cost;
    }
    for (i = 0, U = 1 << (rmid - lmid); i < U; i++) {
      res = 0, cost = 0;
      for (j = lmid + 1; cost <= y && j <= rmid; j++)
        if ((i >> (j - lmid - 1)) & 1)
          res += v[j], cost += w[j];
      if (cost <= y)
        f2[++cnt2] = res, g2[cnt2] = cost;
    }
    for (i = 0, U = 1 << (tot - rmid); i < U; i++) {
      res = 0, cost = 0;
      for (j = rmid + 1; cost <= y && j <= tot; j++)
        if ((i >> (j - rmid - 1)) & 1)
          res += v[j], cost += w[j];
      if (cost <= y)
        f3[++cnt3] = res, g3[cnt3] = cost;
    }
    for (i = 1; i <= cnt1; i++)
      id1[i] = i;
    for (i = 1; i <= cnt2; i++)
      id2[i] = i;
    for (i = 1; i <= cnt3; i++)
      id3[i] = i;
    sort(id1 + 1, id1 + 1 + cnt1, [](int a, int b) { return g1[a] < g1[b]; });
    sort(id2 + 1, id2 + 1 + cnt2, [](int a, int b) { return g2[a] < g2[b]; });
    sort(id3 + 1, id3 + 1 + cnt3, [](int a, int b) { return g3[a] < g3[b]; });
    Ans = 0;
    for (i = 1; i <= cnt3; i++)
      f3[id3[i]] = max(f3[id3[i]], f3[id3[i - 1]]);
    for (i = 1; i <= cnt1; i++)
      for (j = 1, k = cnt3; j <= cnt2; j++) {
        while (k && g1[id1[i]] + g2[id2[j]] + g3[id3[k]] > y)
          k--;
        if (!k)
          break;
        Ans = max(Ans, f1[id1[i]] + f2[id2[j]] + f3[id3[k]]);
      }
    write(Ans);
    pc('\n');
  }
  IO::end();
  return 0;
}