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

// #include<cstdio>
// #include<cassert>
// #include<iostream>
// #include<cstring>
// #include<algorithm>
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define MAX ((int)1e8 + 5)
#define MAXL ((ll)1e18 + 5)
#define MAX_X ((ll)1e5 + 2)
#define pi (2.0 * acos(0))
#define M ((int)1e6 + 7)
#define MOD ((int)1e9 + 7)
#define NN ((int)1e6 + 7)
#define N ((int)1e5 + 7)
#define eps (0)
#define fastio ios_base::sync_with_stdio(false), cin.tie(NULL)
#define logn 29
#define endl "\\n"
#define mp make_pair
#define BUCK 105
#define LEF (idx << 1)
#define RIG ((idx << 1) | 1)
// #define int ll

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef unsigned long long ull;

/*fast io
ios_base::sync_with_stdio(false);
cin.tie(NULL);
*/

typedef tree<pair<ll, pair<ll, ll>>, null_type, less<pair<ll, pair<ll, ll>>>,
             rb_tree_tag, tree_order_statistics_node_update>
    o_set;
/// o_set s;
/// s.order_of_key(k) : Number of items strictly smaller than k .
/// *(s.find_by_order(k)) : K-th element in a set (counting from zero).

int val[2 + (1 << 18)], wgh[2 + (1 << 18)];
pair<int, int> ans[2][2 + (1 << 9)], ans1[2][2 + (1 << 9)];

int main() {
  fastio;
  int n;
  cin >> n;
  for (int i = 1; i <= n; i++)
    cin >> val[i] >> wgh[i];
  int q;
  cin >> q;
  while (q--) {
    int a, l;
    cin >> a >> l;
    vector<pair<int, int>> vec;
    while (a != 0) {
      vec.push_back({wgh[a], val[a]});
      a /= 2;
    }
    int tot = (1 + (int)vec.size()) / 2;
    int mask = 1 << tot;
    ans[0][0] = ans1[0][0] = {0, 0};
    bool cur = 0;
    for (int j = 0; j < tot; j++) {
      int lim = 1 << j;
      for (int i = 0; i < lim; i++) {
        ans[cur][i + lim].first = ans[cur][i].first + vec[j].first;
        ans[cur][i + lim].second = ans[cur][i].second + vec[j].second;
      }
      cur = !cur;
      int i = 0, k = 0, id = 0;
      while (i < lim && k < lim) {
        if (ans[!cur][i] < ans[!cur][k + lim]) {
          ans[cur][id] = ans[!cur][i++];
        } else {
          ans[cur][id] = ans[!cur][lim + k];
          k++;
        }
        id++;
      }
      while (i < lim) {
        ans[cur][id] = ans[!cur][i++];
        id++;
        i++;
      }
      while (k < lim) {
        ans[cur][id] = ans[!cur][lim + k];
        k++;
        id++;
      }
    }
    bool cur1 = cur;

    //        for(int i = 0 ; i<mask ; i++){
    //            ans[i] = {0,0};
    //            for(int j = 0; j<tot ; j++){
    //                if(i&(1<<j)){
    //                    ans[i].first += vec[j].first;
    //                    ans[i].second += vec[j].second;
    //                }
    //            }
    //        }

    int tot1 = (int)vec.size() - tot;

    int mask1 = 1 << tot1;
    cur = 0;
    for (int j = 0; j < tot1; j++) {
      int lim = 1 << j;
      for (int i = 0; i < lim; i++) {
        ans1[cur][i + lim].first = ans1[cur][i].first + vec[j + tot].first;
        ans1[cur][i + lim].second = ans1[cur][i].second + vec[j + tot].second;
      }

      cur = !cur;
      int i = 0, k = 0, id = 0;
      while (i < lim && k < lim) {
        if (ans1[!cur][i] < ans1[!cur][k + lim]) {
          ans1[cur][id] = ans1[!cur][i++];
        } else {
          ans1[cur][id] = ans1[!cur][lim + k];
          k++;
        }
        id++;
      }
      while (i < lim) {
        ans1[cur][id] = ans1[!cur][i++];
        id++;
        i++;
      }
      while (k < lim) {
        ans1[cur][id] = ans1[!cur][lim + k];
        k++;
        id++;
      }
    }

    //        for(int i = 0 ; i<mask1 ; i++){
    //            ans1[i] = {0,0};
    //            for(int j = 0; j<tot1 ; j++){
    //                if(i&(1<<j)){
    //                    ans1[i].first += vec[j+tot].first;
    //                    ans1[i].second += vec[j+tot].second;
    //                }
    //            }
    //        }

    //        sort(ans1,ans1+mask1);
    //        sort(ans,ans+mask);
    for (int i = 1; i < mask1; i++) {
      ans1[cur][i].second = max(ans1[cur][i].second, ans1[cur][i - 1].second);
    }
    swap(cur, cur1);
    int now = mask1 - 1;
    int ansss = 0;
    for (int i = 0; i < mask; i++) {
      int rem = l - ans[cur][i].first;
      if (rem < 0)
        break;
      while (ans1[cur1][now].first > rem)
        now--;
      ansss = max(ansss, ans[cur][i].second + ans1[cur1][now].second);
    }

    cout << ansss << endl;
  }
  return 0;
}


Error: TLE

Fixed submission:

// #include<cstdio>
// #include<cassert>
// #include<iostream>
// #include<cstring>
// #include<algorithm>
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define MAX ((int)1e8 + 5)
#define MAXL ((ll)1e18 + 5)
#define MAX_X ((ll)1e5 + 2)
#define pi (2.0 * acos(0))
#define M ((int)1e6 + 7)
#define MOD ((int)1e9 + 7)
#define NN ((int)1e6 + 7)
#define N ((int)1e5 + 7)
#define eps (0)
#define fastio ios_base::sync_with_stdio(false), cin.tie(NULL)
#define logn 29
#define endl "\\n"
#define mp make_pair
#define BUCK 105
#define LEF (idx << 1)
#define RIG ((idx << 1) | 1)
// #define int ll

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef unsigned long long ull;

/*fast io
ios_base::sync_with_stdio(false);
cin.tie(NULL);
*/

typedef tree<pair<ll, pair<ll, ll>>, null_type, less<pair<ll, pair<ll, ll>>>,
             rb_tree_tag, tree_order_statistics_node_update>
    o_set;
/// o_set s;
/// s.order_of_key(k) : Number of items strictly smaller than k .
/// *(s.find_by_order(k)) : K-th element in a set (counting from zero).

int val[2 + (1 << 18)], wgh[2 + (1 << 18)];
pair<int, int> ans[2 + (1 << 9)], ans1[2 + (1 << 9)];

int main() {
  fastio;
  int n;
  cin >> n;
  for (int i = 1; i <= n; i++)
    cin >> val[i] >> wgh[i];
  int q;
  cin >> q;
  while (q--) {
    int a, l;
    cin >> a >> l;
    vector<pair<int, int>> vec;
    while (a != 0) {
      vec.push_back({wgh[a], val[a]});
      a /= 2;
    }
    int tot = (1 + (int)vec.size()) / 2;
    int mask = 1 << tot;
    ans[0] = ans1[0] = {0, 0};
    for (int j = 0; j < tot; j++) {
      int lim = 1 << j;
      for (int i = 0; i < lim; i++) {
        ans[i + lim].first = ans[i].first + vec[j].first;
        ans[i + lim].second = ans[i].second + vec[j].second;
      }
    }

    //        for(int i = 0 ; i<mask ; i++){
    //            ans[i] = {0,0};
    //            for(int j = 0; j<tot ; j++){
    //                if(i&(1<<j)){
    //                    ans[i].first += vec[j].first;
    //                    ans[i].second += vec[j].second;
    //                }
    //            }
    //        }

    int tot1 = (int)vec.size() - tot;

    int mask1 = 1 << tot1;

    for (int j = 0; j < tot1; j++) {
      int lim = 1 << j;
      for (int i = 0; i < lim; i++) {
        ans1[i + lim].first = ans1[i].first + vec[j + tot].first;
        ans1[i + lim].second = ans1[i].second + vec[j + tot].second;
      }
    }

    //        for(int i = 0 ; i<mask1 ; i++){
    //            ans1[i] = {0,0};
    //            for(int j = 0; j<tot1 ; j++){
    //                if(i&(1<<j)){
    //                    ans1[i].first += vec[j+tot].first;
    //                    ans1[i].second += vec[j+tot].second;
    //                }
    //            }
    //        }

    sort(ans1, ans1 + mask1);
    sort(ans, ans + mask);
    for (int i = 1; i < mask1; i++) {
      ans1[i].second = max(ans1[i].second, ans1[i - 1].second);
    }
    int cur = mask1 - 1;
    int ansss = 0;
    for (int i = 0; i < mask; i++) {
      int rem = l - ans[i].first;
      if (rem < 0)
        break;
      while (ans1[cur].first > rem)
        cur--;
      ansss = max(ansss, ans[i].second + ans1[cur].second);
    }

    cout << ansss << endl;
  }
  return 0;
}