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

#include <bits/stdc++.h>

using namespace std;

typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
typedef long double ld;

const int inf = 1e9;
const ll inf64 = 1e18;

const int N = (1 << 18) + 5;
const int LOG = 20;
const int Q = 1e5 + 5;

int n, q;
int value[N], weight[N];
vector<pii> qs[N];
int res[Q];
int bit[1 << 12];

void precalc() {
  for (int i = 0; i < 12; i++)
    bit[1 << i] = i;
}

void solve(const vector<pii> &qq, int lsz, int rsz, pii *lar, pii *rar) {
  int LL = 1 << lsz;
  int RR = 1 << rsz;

  //    for (int i = 0; i < LL; i++) {
  //        cout << "(" << lar[i].first << " " << lar[i].second << ") ";
  //    }
  //    cout << " | ";
  //    for (int i = 0; i < RR; i++) {
  //        cout << "(" << rar[i].first << " " << rar[i].second << ") ";
  //    }
  //    cout << "\\n";

  for (auto pp : qq) {
    int L, id;
    tie(L, id) = pp;

    for (int i = 0; i < LL; i++) {
      if (lar[i].first <= L)
        res[id] = max(res[id], lar[i].second);
    }

    for (int i = 0; i < RR; i++) {
      if (rar[i].first <= L)
        res[id] = max(res[id], rar[i].second);
    }

    for (int j = 0, mx = 0, i = RR - 1; i >= 0; i--) {
      while (j < LL && lar[j].first + rar[i].first <= L)
        mx = max(mx, lar[j++].second);
      if (rar[i].first <= L)
        res[id] = max(res[id], mx + rar[i].second);
    }

    //        cout << L << " : " << res[id] << "\\n";
  }
  //    cout << "\\n==============\\n";
}

void update(pii *dp, int sz, int w, int v) {
  int iters = (1 << (sz - 1));
  for (int mask = 0; mask < iters; mask++) {
    dp[mask | iters] = {dp[mask].first + w, dp[mask].second + v};
  }
}

pii _lar[1 << 12], _rar[1 << 12];
pii lar[1 << 12], rar[1 << 12];

void dfs(int v, int h = 1) {
  if (v > n)
    return;
  if (h <= 9) {
    update(_lar, h, weight[v], value[v]);
  } else {
    update(_rar, h - 9, weight[v], value[v]);
  }
  if (h == 9) {
    memcpy(lar, _lar, sizeof(pii) * (1 << h));
    sort(lar, lar + (1 << h));
  }
  if (!qs[v].empty()) {
    int lsz = min(h, 9);
    int rsz = h - lsz;

    memcpy(rar, _rar, sizeof(pii) * (1 << rsz));
    sort(rar, rar + (1 << rsz));

    if (h < 9) {
      memcpy(lar, _lar, sizeof(pii) * (1 << lsz));
      sort(lar, lar + (1 << lsz));
    }

    solve(qs[v], lsz, rsz, lar, rar);
  }
  dfs(v * 2, h + 1);
  dfs(v * 2 + 1, h + 1);
}

int main() {

  precalc();

#ifdef DEBUG
  freopen("input.txt", "r", stdin);
#endif

  ios_base::sync_with_stdio(0);
  cin.tie(0);

  cin >> n;

  for (int v = 1; v <= n; v++) {
    cin >> value[v] >> weight[v];
  }

  cin >> q;

  for (int iter = 0; iter < q; iter++) {
    int v, L;
    cin >> v >> L;
    qs[v].emplace_back(L, iter);
  }

  dfs(1);

  for (int i = 0; i < q; i++) {
    cout << res[i] << "\\n";
  }

  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>

/**
 * Author: Sergey Kopeliovich (Burunduk30@gmail.com)
 */

#define VERSION "0.1.4"

#include <algorithm>
#include <cassert>
#include <cstdio>

/** Fast allocation */

#ifdef FAST_ALLOCATOR_MEMORY
int allocator_pos = 0;
char allocator_memory[(int)FAST_ALLOCATOR_MEMORY];
inline void *operator new(size_t n) {
  char *res = allocator_memory + allocator_pos;
  allocator_pos += n;
  assert(allocator_pos <= (int)FAST_ALLOCATOR_MEMORY);
  return (void *)res;
}
inline void operator delete(void *) noexcept {}
// inline void * operator new [] ( size_t ) { assert(0); }
// inline void operator delete [] ( void * ) { assert(0); }
#endif

/** Fast input-output */

template <class T = int> inline T readInt();
inline double readDouble();
inline int readUInt();
inline int readChar(); // first non-blank character
inline void readWord(char *s);
inline bool readLine(char *s); // do not save '\\n'
inline bool isEof();
inline int getChar();
inline int peekChar();
inline bool seekEof();
inline void skipBlanks();

template <class T> inline void writeInt(T x, char end = 0, int len = -1);
inline void writeChar(int x);
inline void writeWord(const char *s);
inline void writeDouble(double x, int len = 0);
inline void flush();

static struct buffer_flusher_t {
  ~buffer_flusher_t() { flush(); }
} buffer_flusher;

/** Read */

static const int buf_size = 4096;

static unsigned char buf[buf_size];
static int buf_len = 0, buf_pos = 0;

inline bool isEof() {
  if (buf_pos == buf_len) {
    buf_pos = 0, buf_len = fread(buf, 1, buf_size, stdin);
    if (buf_pos == buf_len)
      return 1;
  }
  return 0;
}

inline int getChar() { return isEof() ? -1 : buf[buf_pos++]; }

inline int peekChar() { return isEof() ? -1 : buf[buf_pos]; }

inline bool seekEof() {
  int c;
  while ((c = peekChar()) != -1 && c <= 32)
    buf_pos++;
  return c == -1;
}

inline void skipBlanks() {
  while (!isEof() && buf[buf_pos] <= 32U)
    buf_pos++;
}

inline int readChar() {
  int c = getChar();
  while (c != -1 && c <= 32)
    c = getChar();
  return c;
}

inline int readUInt() {
  int c = readChar(), x = 0;
  while ('0' <= c && c <= '9')
    x = x * 10 + c - '0', c = getChar();
  return x;
}

template <class T> inline T readInt() {
  int s = 1, c = readChar();
  T x = 0;
  if (c == '-')
    s = -1, c = getChar();
  else if (c == '+')
    c = getChar();
  while ('0' <= c && c <= '9')
    x = x * 10 + c - '0', c = getChar();
  return s == 1 ? x : -x;
}

inline double readDouble() {
  int s = 1, c = readChar();
  double x = 0;
  if (c == '-')
    s = -1, c = getChar();
  while ('0' <= c && c <= '9')
    x = x * 10 + c - '0', c = getChar();
  if (c == '.') {
    c = getChar();
    double coef = 1;
    while ('0' <= c && c <= '9')
      x += (c - '0') * (coef *= 1e-1), c = getChar();
  }
  return s == 1 ? x : -x;
}

inline void readWord(char *s) {
  int c = readChar();
  while (c > 32)
    *s++ = c, c = getChar();
  *s = 0;
}

inline bool readLine(char *s) {
  int c = getChar();
  while (c != '\\n' && c != -1)
    *s++ = c, c = getChar();
  *s = 0;
  return c != -1;
}

/** Write */

static int write_buf_pos = 0;
static char write_buf[buf_size];

inline void writeChar(int x) {
  if (write_buf_pos == buf_size)
    fwrite(write_buf, 1, buf_size, stdout), write_buf_pos = 0;
  write_buf[write_buf_pos++] = x;
}

inline void flush() {
  if (write_buf_pos)
    fwrite(write_buf, 1, write_buf_pos, stdout), write_buf_pos = 0;
}

template <class T> inline void writeInt(T x, char end, int output_len) {
  if (x < 0)
    writeChar('-'), x = -x;

  char s[24];
  int n = 0;
  while (x || !n)
    s[n++] = '0' + x % 10, x /= 10;
  while (n < output_len)
    s[n++] = '0';
  while (n--)
    writeChar(s[n]);
  if (end)
    writeChar(end);
}

inline void writeWord(const char *s) {
  while (*s)
    writeChar(*s++);
}

inline void writeDouble(double x, int output_len) {
  if (x < 0)
    writeChar('-'), x = -x;
  int t = (int)x;
  writeInt(t), x -= t;
  writeChar('.');
  for (int i = output_len - 1; i > 0; i--) {
    x *= 10;
    t = std::min(9, (int)x);
    writeChar('0' + t), x -= t;
  }
  x *= 10;
  t = std::min(9, (int)(x + 0.5));
  writeChar('0' + t);
}

using namespace std;

typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
typedef long double ld;

const int inf = 1e9;
const ll inf64 = 1e18;

const int N = (1 << 18) + 5;
const int LOG = 20;
const int Q = 1e5 + 5;

int n, q;
int value[N], weight[N];
vector<pii> qs[N];
int res[Q];

int a[LOG];
int b[LOG];
int sz;

int tsz;
int ta[LOG];
int tb[LOG];

int LL, RR;
pii lar[1 << 12];
pii rar[1 << 12];
int bit[1 << 12];

void precalc() {
  for (int i = 0; i < 12; i++)
    bit[1 << i] = i;
}

void solve(const vector<pii> &qq, bool do_sort = true) {
  if (sz == 1) {
    for (auto p : qq)
      res[p.second] = b[0] <= p.first ? a[0] : 0;
    return;
  }

  //    for (int i = 0; i < sz; i++)
  //        cout << a[i] << " " << b[i] << "\\n";

  int lsz = sz / 2;
  int rsz = sz - lsz;

  LL = 1 << lsz;
  RR = 1 << rsz;

  for (int mask = 0; mask < LL; mask++) {
    if (mask == 0) {
      lar[mask] = {0, 0};
      continue;
    }
    int i = bit[mask & -mask];
    int tmask = mask ^ (1 << i);
    lar[mask] = {lar[tmask].first + b[i], lar[tmask].second + a[i]};
    for (auto pp : qq) {
      int L, id;
      tie(L, id) = pp;
      if (lar[mask].first <= L)
        res[id] = max(res[id], lar[mask].second);
    }
  }

  for (int mask = 0; mask < RR; mask++) {
    if (mask == 0) {
      rar[mask] = {0, 0};
      continue;
    }
    int i = bit[mask & -mask];
    int tmask = mask ^ (1 << i);
    rar[mask] = {rar[tmask].first + b[lsz + i], rar[tmask].second + a[lsz + i]};
  }

  if (do_sort)
    sort(lar, lar + LL);
  sort(rar, rar + RR);

  for (auto pp : qq) {
    int L, id;
    tie(L, id) = pp;
    for (int j = 0, mx = 0, i = RR - 1; i >= 0; i--) {
      while (j < LL && lar[j].first + rar[i].first <= L)
        mx = max(mx, lar[j++].second);
      if (rar[i].first <= L)
        res[id] = max(res[id], mx + rar[i].second);
    }
  }
}

int main() {

  precalc();

#ifdef DEBUG
  freopen("input.txt", "r", stdin);
#endif

  //    ios_base::sync_with_stdio(0);
  //    cin.tie(0);

  //    cin >> n;
  n = readInt();

  for (int v = 1; v <= n; v++) {
    //        cin >> value[v] >> weight[v];
    value[v] = readInt();
    weight[v] = readInt();
  }

  //    cin >> q;
  q = readInt();

  for (int iter = 0; iter < q; iter++) {
    int v, L;
    //        cin >> v >> L;
    v = readInt();
    L = readInt();
    qs[v].emplace_back(L, iter);
  }

  for (int v = 1; v <= n; v++) {
    if (qs[v].empty())
      continue;

    int vv = v;
    tsz = 0;
    while (v >= 1) {
      ta[tsz] = value[v];
      tb[tsz] = weight[v];
      tsz++;
      v /= 2;
    }
    v = vv;

    reverse(ta, ta + tsz);
    reverse(tb, tb + tsz);
    int _lcp = 0;
    while (_lcp < tsz && _lcp < sz && ta[_lcp] == a[_lcp] &&
           tb[_lcp] == b[_lcp])
      _lcp++;

    bool do_sort = _lcp < 10;
    for (int i = 0; i < tsz; i++)
      a[i] = ta[i], b[i] = tb[i];
    sz = tsz;

    solve(qs[v]);
  }

  for (int i = 0; i < q; i++) {
    //        cout << res[i] << "\\n";
    writeInt(res[i], '\\n');
  }

  return 0;
}