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

// while (clock()<=69*CLOCKS_PER_SEC)
// #pragma comment(linker, "/stack:200000000")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("Ofast")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
// #pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define pb push_back
#define SZ(x) ((int)(x).size())
#define ALL(x) x.begin(), x.end()
#define all(x) x.begin(), x.end()
#define fi first
#define se second
#define _upgrade                                                               \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(0);                                                                  \\
  cout.tie(0);
#define erase_duplicates(x)                                                    \\
  sort(all(x));                                                                \\
  (x).resize(distance((x).begin(), unique(all(x))));

using namespace std;
using namespace __gnu_pbds;
template <typename T>
using ordered_set =
    tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

// X.find_by_order(k); - zwraca iterator na k-ty element (numeracja od zerowego)
// X.order_of_key(k); - zwraca liczbę elementów ostro mniejszych niż k

typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef vector<PII> VPII;
typedef vector<PLL> VPLL;
typedef vector<LL> VLL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<char> VC;
typedef long double LD;
typedef pair<LD, LD> PLD;
typedef vector<LD> VLD;
typedef vector<PLD> VPLD;

template <class TH> void _dbg(const char *sdbg, TH h) {
  cerr << sdbg << " = " << h << endl;
}
template <class TH, class... TA> void _dbg(const char *sdbg, TH h, TA... a) {
  while (*sdbg != ',')
    cerr << *sdbg++;
  cerr << " = " << h << ", ";
  _dbg(sdbg + 1, a...);
}

#ifdef LOCAL
#define dbg(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#else
#define dbg(...)
#define cerr                                                                   \\
  if (0)                                                                       \\
  cout
#endif

const int maxn = (1e6) + 7;
const int maxk = 20;
const int inf = (1e9) + 7;
const LL LLinf = ((LL)1e18) + 7LL;
const LD eps = 1e-9;
const LL mod = 1e9 + 7;

// ***************************** CODE ***************************** //

int v[maxn], w[maxn];
VPII odp[maxn];

bool por(PII a, PII b) {
  if (a.se != b.se)
    return a.se < b.se;
  return a.fi > b.fi;
}

void normuj(VPII &a, int x) {
  sort(all(a), por);
  for (auto s : a)
    if (SZ(odp[x]) == 0 or odp[x].back().fi < s.fi)
      odp[x].pb(s);
  for (int i = 0; i + 1 < SZ(odp[x]); i++) {
    assert(odp[x][i].fi < odp[x][i + 1].fi);
    assert(odp[x][i].se < odp[x][i + 1].se);
  }
}

void rob(int x, int d = 0) {
  int ile = 0;
  int cur = x;
  while (cur >= (1 << d)) {
    ile++;
    cur /= 2;
  }
  // dbg(x, d, SZ(tmp));
  VPII res;
  for (int i = 0; i < (1 << ile); i++) {
    PII c = {0, 0};
    for (int j = 0; j < ile; j++)
      if ((1 << j) & i)
        c = {c.fi + v[x >> j], c.se + w[x >> j]};
    res.pb(c);
  }
  normuj(res, x);
}

int d = 0;

void flip(int x) {
  if (SZ(odp[x]) > 0)
    return;
  if (x < (1 << (d + 1)))
    rob(x, 0);
  else
    rob(x, d + 1);
}

int result(int a, int b, int l) {
  flip(a);
  flip(b);
  int res = 0;
  int wskb = SZ(odp[b]) - 1;
  for (int i = 0; i < SZ(odp[a]); i++) {
    while (wskb >= 0 and odp[b][wskb].se + odp[a][i].se > l)
      wskb--;
    if (wskb >= 0)
      res = max(res, odp[b][wskb].fi + odp[a][i].fi);
  }
  return res;
}

int main() {
  _upgrade int n = (1 << 18) - 1;
  cin >> n;
  for (int i = 1; i <= n; i++) {
    v[i] = i;
    w[i] = 1;
    cin >> v[i] >> w[i];
  }
  while (1LL << (2 * d) <= n)
    d++;
  d++;
  odp[0] = {{0, 0}};
  for (int i = (1 << d); i < (1 << (d + 1)); i++)
    flip(i);
  int q = 10000;
  cin >> q;
  while (q--) {
    int gdzie = rand() % n + 1;
    int l = rand() % 10000;
    cin >> gdzie >> l;
    int x = gdzie;
    while ((1 << (d + 1)) <= x)
      x /= 2;
    if (x == gdzie)
      x = 0;
    cout << result(gdzie, x, l) << "\\n";
  }

  return 0;
}


Error: TLE

Fixed submission:

// while (clock()<=69*CLOCKS_PER_SEC)
// #pragma comment(linker, "/stack:200000000")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("Ofast")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
// #pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#define pb push_back
#define SZ(x) ((int)(x).size())
#define ALL(x) x.begin(), x.end()
#define all(x) x.begin(), x.end()
#define fi first
#define se second
#define _upgrade                                                               \\
  ios_base::sync_with_stdio(0);                                                \\
  cin.tie(0);                                                                  \\
  cout.tie(0);
#define erase_duplicates(x)                                                    \\
  sort(all(x));                                                                \\
  (x).resize(distance((x).begin(), unique(all(x))));

using namespace std;
using namespace __gnu_pbds;
template <typename T>
using ordered_set =
    tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

// X.find_by_order(k); - zwraca iterator na k-ty element (numeracja od zerowego)
// X.order_of_key(k); - zwraca liczbę elementów ostro mniejszych niż k

typedef long long LL;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef vector<PII> VPII;
typedef vector<PLL> VPLL;
typedef vector<LL> VLL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef vector<char> VC;
typedef long double LD;
typedef pair<LD, LD> PLD;
typedef vector<LD> VLD;
typedef vector<PLD> VPLD;

template <class TH> void _dbg(const char *sdbg, TH h) {
  cerr << sdbg << " = " << h << endl;
}
template <class TH, class... TA> void _dbg(const char *sdbg, TH h, TA... a) {
  while (*sdbg != ',')
    cerr << *sdbg++;
  cerr << " = " << h << ", ";
  _dbg(sdbg + 1, a...);
}

#ifdef LOCAL
#define dbg(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#else
#define dbg(...)
#define cerr                                                                   \\
  if (0)                                                                       \\
  cout
#endif

const int maxn = (1e6) + 7;
const int maxk = 20;
const int inf = (1e9) + 7;
const LL LLinf = ((LL)1e18) + 7LL;
const LD eps = 1e-9;
const LL mod = 1e9 + 7;

// ***************************** CODE ***************************** //

int v[maxn], w[maxn];
VPII odp[maxn];

bool por(PII a, PII b) {
  if (a.se != b.se)
    return a.se < b.se;
  return a.fi > b.fi;
}

void normuj(VPII &a, int x) {
  sort(all(a), por);
  for (auto s : a)
    if (SZ(odp[x]) == 0 or odp[x].back().fi < s.fi)
      odp[x].pb(s);
}

void rob(int x, int d = 0) {
  int ile = 1;
  int cur = x;
  while (cur >= (1 << d)) {
    ile++;
    cur /= 2;
  }
  // dbg(x, d, SZ(tmp));
  VPII res;
  for (int i = 0; i < (1 << ile); i++) {
    PII c = {0, 0};
    for (int j = 0; j < ile; j++)
      if ((1 << j) & i)
        c = {c.fi + v[x >> j], c.se + w[x >> j]};
    res.pb(c);
  }
  normuj(res, x);
}

int result(int a, int b, int l) {
  int res = 0;
  int wskb = SZ(odp[b]) - 1;
  for (int i = 0; i < SZ(odp[a]); i++) {
    while (wskb >= 0 and odp[b][wskb].se + odp[a][i].se > l)
      wskb--;
    if (wskb >= 0)
      res = max(res, odp[b][wskb].fi + odp[a][i].fi);
  }
  return res;
}

int d = 0;

void flip(int x) {
  if (SZ(odp[x]) > 0)
    return;
  if (x < (1 << (d + 1)))
    rob(x, 0);
  else
    rob(x, d + 1);
}

int main() {
  _upgrade int n = (1 << 18) - 1;
  cin >> n;
  for (int i = 1; i <= n; i++) {
    // v[i] = w[i] = i;
    cin >> v[i] >> w[i];
  }
  while ((1LL << (2 * d) < n))
    d++;
  d++;
  odp[0] = {{0, 0}};
  for (int i = 1; i <= n; i++)
    flip(i);
  // for(int i = 0;i < 4;i++)
  // {
  //   dbg(i);
  //   for(int j = 0;j < SZ(odp[i]);j++)
  //     dbg(odp[i][j].fi, odp[i][j].se);
  // }
  int q = 0;
  cin >> q;
  while (q--) {
    int gdzie, l;
    cin >> gdzie >> l;
    int x = gdzie;
    while ((1 << (d + 1)) <= x)
      x /= 2;
    if (x == gdzie)
      x = 0;
    cout << result(gdzie, x, l) << "\\n";
  }

  return 0;
}