Problem p02648 (C++)

Buggy submission (status: Runtime Error):
#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC optimize("unroll-loops")

#include <algorithm>
#include <bitset> //UWAGA - w czasie kompilacji musi byc znany rozmiar wektora - nie mozna go zmienic
#include <cassert>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <fstream>
#include <iomanip> //do setprecision
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <vector>
using namespace std;

#define FOR(i, b, e) for (int i = (b); i < (e); ++i)
#define FORQ(i, b, e) for (int i = (b); i <= (e); ++i)
#define FORD(i, b, e) for (int i = (b)-1; i >= (e); --i)
#define REP(x, n) for (int x = 0; x < (n); ++x)
#define ALL(u) (u).begin(), (u).end()

#define ST first
#define ND second
#define PB push_back
#define MP make_pair
#define LL long long
#define ULL unsigned LL
#define LD long double

typedef pair<int, int> PII;

const double pi =
    3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342;

const int MR = 1e5 + 10;
const int MS = 1 << 18;
const int LH = 10;

LL dp[512][MR];

PII t[MS];
int h[MS];

int main() {
  int N;
  scanf("%d", &N);
  FORQ(i, 1, N)
  scanf("%d%d", &t[i].first, &t[i].second);
  // wylicz dp dla roota, h[root] == 0
  FOR(i, t[1].second, MR)
  dp[1][i] = t[1].first;
  FORQ(v, 2, N) {
    // wylicz h
    int par = v / 2;
    h[v] = h[par] + 1;
    if (h[v] < LH) {
      // wylicz dp do meet in the middle
      FOR(i, 1, t[v].second)
      dp[v][i] = dp[par][i];
      FOR(i, t[v].second, MR)
      dp[v][i] = max(dp[par][i], dp[par][i - t[v].second] + t[v].first);
    }
  }

  // jedz query
  int Q;
  scanf("%d", &Q);
  REP(xxx, Q) {
    int v, L;
    scanf("%d%d", &v, &L);

    // zobacz, czy od razu mamy wynik
    if (h[v] < LH) {
      printf("%lld\n", dp[v][L]);
      continue;
    }

    // wez kazdy podzbior rodzicow o glebokosci >= LH
    vector<int> par;
    while (h[v] >= LH) {
      par.push_back(v);
      v >>= 1;
    }

    // teraz w v mamy rodzica o h[v] < LH i tam mamy wyliczone dp
    LL res = 0;
    REP(mask, 1 << par.size()) {
      int W = 0;
      LL V = 0;
      REP(i, par.size())
      if (mask & (1 << i)) {
        V += t[par[i]].first;
        W += t[par[i]].second;
        if (W > L)
          break;
      }

      if (W <= L)
        res = max(res, V + dp[v][L - W]);
    }

    printf("%lld\n", res);
  }

  return 0;
}

// FOR GNU C++ use the following pattern:
// Uncomment the code below and change your main into main2
// It does not build in MS C++
// But it does increase the stack size from 256 MB on CF and uses GNU C++

// #include <Processthreadsapi.h>
// #include <iostream>
// #include <Synchapi.h>
// #include <windows.h>
// #include <process.h>
//
// DWORD WINAPI MyThreadFunction(LPVOID lpParam) {
//     main2(nullptr);
//     return 0;
// }
// int main() {
//     auto h = CreateThread(nullptr, 1024 << 20, MyThreadFunction, nullptr,
//     STACK_SIZE_PARAM_IS_A_RESERVATION, nullptr); WaitForSingleObject(h,
//     INFINITE);
// }

Fixed submission:
#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC optimize("unroll-loops")

#include <algorithm>
#include <bitset> //UWAGA - w czasie kompilacji musi byc znany rozmiar wektora - nie mozna go zmienic
#include <cassert>
#include <chrono>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <fstream>
#include <iomanip> //do setprecision
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <vector>
using namespace std;

#define FOR(i, b, e) for (int i = (b); i < (e); ++i)
#define FORQ(i, b, e) for (int i = (b); i <= (e); ++i)
#define FORD(i, b, e) for (int i = (b)-1; i >= (e); --i)
#define REP(x, n) for (int x = 0; x < (n); ++x)
#define ALL(u) (u).begin(), (u).end()

#define ST first
#define ND second
#define PB push_back
#define MP make_pair
#define LL long long
#define ULL unsigned LL
#define LD long double

typedef pair<int, int> PII;

const double pi =
    3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342;

const int MR = 1e5 + 10;
const int MS = 1 << 18;
const int LH = 10;

LL dp[1024][MR];

PII t[MS];
int h[MS];

int main() {
  int N;
  scanf("%d", &N);
  FORQ(i, 1, N)
  scanf("%d%d", &t[i].first, &t[i].second);
  // wylicz dp dla roota, h[root] == 0
  FOR(i, t[1].second, MR)
  dp[1][i] = t[1].first;
  FORQ(v, 2, N) {
    // wylicz h
    int par = v / 2;
    h[v] = h[par] + 1;
    if (h[v] < LH) {
      // wylicz dp do meet in the middle
      FOR(i, 1, t[v].second)
      dp[v][i] = dp[par][i];
      FOR(i, t[v].second, MR)
      dp[v][i] = max(dp[par][i], dp[par][i - t[v].second] + t[v].first);
    }
  }

  // jedz query
  int Q;
  scanf("%d", &Q);
  REP(xxx, Q) {
    int v, L;
    scanf("%d%d", &v, &L);

    // zobacz, czy od razu mamy wynik
    if (h[v] < LH) {
      printf("%lld\n", dp[v][L]);
      continue;
    }

    // wez kazdy podzbior rodzicow o glebokosci >= LH
    vector<int> par;
    while (h[v] >= LH) {
      par.push_back(v);
      v >>= 1;
    }

    // teraz w v mamy rodzica o h[v] < LH i tam mamy wyliczone dp
    LL res = 0;
    REP(mask, 1 << par.size()) {
      int W = 0;
      LL V = 0;
      REP(i, par.size())
      if (mask & (1 << i)) {
        V += t[par[i]].first;
        W += t[par[i]].second;
        if (W > L)
          break;
      }

      if (W <= L)
        res = max(res, V + dp[v][L - W]);
    }

    printf("%lld\n", res);
  }

  return 0;
}

// FOR GNU C++ use the following pattern:
// Uncomment the code below and change your main into main2
// It does not build in MS C++
// But it does increase the stack size from 256 MB on CF and uses GNU C++

// #include <Processthreadsapi.h>
// #include <iostream>
// #include <Synchapi.h>
// #include <windows.h>
// #include <process.h>
//
// DWORD WINAPI MyThreadFunction(LPVOID lpParam) {
//     main2(nullptr);
//     return 0;
// }
// int main() {
//     auto h = CreateThread(nullptr, 1024 << 20, MyThreadFunction, nullptr,
//     STACK_SIZE_PARAM_IS_A_RESERVATION, nullptr); WaitForSingleObject(h,
//     INFINITE);
// }