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

#include <algorithm>
#include <assert.h>
#include <bitset>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
using namespace std;

#define x first
#define y second
const int N = 1 << 19;
int a[N], b[N];
int limits = 6;
const int C = 12;
vector<pair<int, int>> v[(1 << C) + 10];
int c[C + 10];
int aa[N], bb[N];

void init(int n) {
  int cnt = 0;
  int m = n;
  while (n >= 1) {
    c[cnt++] = n;
    n >>= 1;
  }

  v[m].push_back(make_pair(0, 0));
  for (int i = 1; i < (1 << cnt); i++) {
    int x = 0, y = 0;
    for (int j = 0; j < cnt; j++)
      if (i & (1 << j)) {
        x += a[c[j]];
        y += b[c[j]];
      }

    v[m].push_back(make_pair(y, x));
  }
  sort(v[m].begin(), v[m].end());
  for (int i = 1; i <= v[m].size(); i++)
    v[m][i].y = max(v[m][i - 1].y, v[m][i].y);
}

void solve() {
  int n, m;
  scanf("%d%d", &n, &m);
  int cnt = 0;
  while (n > (1 << C)) {
    c[cnt++] = n;
    n >>= 1;
  }

  int ans = 0;
  for (int i = 0; i < (1 << cnt); i++) {
    int x = 0, y = 0;
    for (int j = 0; j < cnt; j++)
      if (i & (1 << j)) {
        x += a[c[j]];
        y += b[c[j]];
      }
    int lt = 0, rt = v[n].size() - 1, mid;
    while (lt <= rt) {
      mid = (lt + rt) >> 1;
      if (y + v[n][mid].x <= m) {
        ans = max(ans, x + v[n][mid].y);
        lt = mid + 1;
      } else
        rt = mid - 1;
    }
  }
  printf("%d\\n", ans);
}

int main() {
  int n;
  scanf("%d", &n);
  for (int i = 1; i <= n; i++)
    scanf("%d%d", &a[i], &b[i]);
  for (int i = 1; i <= (1 << C); i++)
    init(i);

  int m;
  scanf("%d", &m);
  while (m--)
    solve();
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <assert.h>
#include <bitset>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
using namespace std;

const int N = 1 << 19;
int a[N], b[N];
int c[18];
int aa[N], aaa[N], bb[N], bbb[N];
int rev[N];
int rak1[N], rak2[N];

bool cmp1(int x, int y) { return aaa[x] < aaa[y]; }

bool cmp2(int x, int y) { return bbb[x] < bbb[y]; }

int lowbit(int x) { return x & (-x); }

void solve() {
  int n, m;
  scanf("%d%d", &n, &m);
  int cnt = 0;
  while (n >= 1) {
    c[cnt++] = n;
    n >>= 1;
  }

  for (int i = 0; i < cnt; i++)
    rev[1 << i] = i;

  if (cnt <= 9) {
    int ans = 0;
    for (int i = 1; i < (1 << cnt); i++) {
      int x = lowbit(i);
      aa[i] = aa[i ^ x] + a[c[rev[x]]];
      aaa[i] = aaa[i ^ x] + b[c[rev[x]]];
      if (aaa[i] <= m)
        ans = max(ans, aa[i]);
    }
    printf("%d\\n", ans);
    return;
  }

  int ans = 0;
  int limits = 9;
  for (int i = 1; i < (1 << limits); i++) {
    int x = lowbit(i);
    aa[i] = aa[i ^ x] + a[c[rev[x]]];
    aaa[i] = aaa[i ^ x] + b[c[rev[x]]];
    if (aaa[i] <= m)
      ans = max(ans, aa[i]);
  }

  for (int i = 1; i < (1 << (cnt - limits)); i++) {
    int x = lowbit(i);
    bb[i] = bb[i ^ x] + a[c[rev[x] + limits]];
    bbb[i] = bbb[i ^ x] + b[c[rev[x] + limits]];
    if (bbb[i] <= m)
      ans = max(ans, bb[i]);
  }

  for (int i = 0; i < (1 << limits); i++)
    rak1[i] = i;
  for (int i = 0; i < (1 << (cnt - limits)); i++)
    rak2[i] = i;
  sort(rak1, rak1 + (1 << limits), cmp1);
  sort(rak2, rak2 + (1 << (cnt - limits)), cmp2);

  for (int i = 1; i < (1 << limits); i++)
    aa[rak1[i]] = max(aa[rak1[i]], aa[rak1[i - 1]]);

  for (int i = 0, j = (1 << limits) - 1; i < (1 << (cnt - limits)); i++) {
    while (j >= 0 && aaa[rak1[j]] + bbb[rak2[i]] > m)
      j--;
    if (j >= 0)
      ans = max(ans, aa[rak1[j]] + bb[rak2[i]]);
    else
      break;
  }
  printf("%d\\n", ans);
}

int main() {
  int n;
  scanf("%d", &n);
  for (int i = 1; i <= n; i++)
    scanf("%d%d", &a[i], &b[i]);

  int m;
  scanf("%d", &m);
  while (m--)
    solve();
  return 0;
}