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

/*
これを入れて実行
g++ code.cpp
./a.out
 */

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstring>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <tuple>
#include <unordered_map>
#include <utility>
#include <vector>

#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

using namespace std;
typedef long long ll;
typedef long double ld;

int dy4[4] = {-1, 0, +1, 0};
int dx4[4] = {0, +1, 0, -1};
int dy8[8] = {-1, -1, 0, 1, 1, 1, 0, -1};
int dx8[8] = {0, 1, 1, 1, 0, -1, -1, -1};

const long long INF = 1LL << 60;
const ll MOD = 1e9 + 7;

bool greaterSecond(const pair<int, int> &f, const pair<int, int> &s) {
  return f.second > s.second;
}

ll gcd(ll a, ll b) {
  if (b == 0)
    return a;
  return gcd(b, a % b);
}

ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }

ll conbinationMemo[100][100];

void cmemoInit() {
  rep(i, 100) {
    rep(j, 100) { conbinationMemo[i][j] = -1; }
  }
}

ll nCr(ll n, ll r) {
  if (conbinationMemo[n][r] != -1)
    return conbinationMemo[n][r];
  if (r == 0 || r == n) {
    return 1;
  } else if (r == 1) {
    return n;
  }
  return conbinationMemo[n][r] = (nCr(n - 1, r) + nCr(n - 1, r - 1));
}

ll nPr(ll n, ll r) {
  r = n - r;
  ll ret = 1;
  for (ll i = n; i >= r + 1; i--)
    ret *= i;
  return ret;
}
//-----------------------ここから-----------
ll n;
vector<ll> v;
vector<ll> w;
vector<vector<ll>> dp;
set<ll> st;
void dfs1(ll now, ll depth) {
  if (depth == max(0LL, (ll)(log2(n) / 2) - 1)) {
    st.insert(now);
    return;
  }

  dfs1(now * 2 + 1, depth + 1);
  dfs1(now * 2 + 2, depth + 1);
}
int main(void) {
  cin >> n;
  v.resize(n + 1);
  w.resize(n + 1);
  dp.resize(551, vector<ll>(1e5 + 1, 0));

  for (ll i = 1; i < n + 1; i++) {
    cin >> v[i] >> w[i];
  }

  dp[0][0] = 0;
  for (ll i = 1; i <= min(n, 550LL); i++) {
    for (ll j = 0; j <= 1e5; j++) {
      ll past = (i) / 2;
      if (j + w[i] <= 1e5)
        dp[i][j + w[i]] = max(dp[i][j + w[i]], dp[past][j] + v[i]);
      dp[i][j] = max(dp[i][j], dp[past][j]);
    }
  }

  // dfs1(0, 0);
  // cout << log2(262143) << endl;

  ll q;
  cin >> q;
  vector<ll> an;
  rep(i, q) {
    ll u, l;
    cin >> u >> l;
    ll now = u;
    ll ans = 0;
    vector<pair<ll, ll>> items;
    if (u < pow(2, 9)) {
      ans = dp[now][l];
      an.push_back(ans);
      continue;
    }
    while (now >= pow(2, 9)) {
      items.push_back({v[now], w[now]});
      now = (now) / 2;
    }

    for (ll bit = 0; bit < (1LL << (ll)items.size()); bit++) {
      ll sumv = 0;
      ll sumw = 0;
      rep(j, items.size()) {
        if (bit & (1LL << j)) {
          sumv += items[j].first;
          sumw += items[j].second;
        }
      }
      if (now >= 550) {
        cout << "e" << endl;
      }
      if (sumw > l)
        continue;
      ans = max(ans, sumv + dp[now][max(0LL, l - sumw)]);
    }
    an.push_back(ans);
  }
  // cout << "f" << dp[0][2] << endl;
  rep(i, an.size()) { cout << an[i] << endl; }
}


Error: TLE

Fixed submission:

/*
これを入れて実行
g++ code.cpp
./a.out
 */

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstring>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string>
#include <tuple>
#include <unordered_map>
#include <utility>
#include <vector>

#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

using namespace std;
typedef long long ll;
typedef long double ld;

int dy4[4] = {-1, 0, +1, 0};
int dx4[4] = {0, +1, 0, -1};
int dy8[8] = {-1, -1, 0, 1, 1, 1, 0, -1};
int dx8[8] = {0, 1, 1, 1, 0, -1, -1, -1};

const long long INF = 1LL << 60;
const ll MOD = 1e9 + 7;

bool greaterSecond(const pair<int, int> &f, const pair<int, int> &s) {
  return f.second > s.second;
}

ll gcd(ll a, ll b) {
  if (b == 0)
    return a;
  return gcd(b, a % b);
}

ll lcm(ll a, ll b) { return a / gcd(a, b) * b; }

ll conbinationMemo[100][100];

void cmemoInit() {
  rep(i, 100) {
    rep(j, 100) { conbinationMemo[i][j] = -1; }
  }
}

ll nCr(ll n, ll r) {
  if (conbinationMemo[n][r] != -1)
    return conbinationMemo[n][r];
  if (r == 0 || r == n) {
    return 1;
  } else if (r == 1) {
    return n;
  }
  return conbinationMemo[n][r] = (nCr(n - 1, r) + nCr(n - 1, r - 1));
}

ll nPr(ll n, ll r) {
  r = n - r;
  ll ret = 1;
  for (ll i = n; i >= r + 1; i--)
    ret *= i;
  return ret;
}
//-----------------------ここから-----------
ll n;
vector<ll> v;
vector<ll> w;
vector<vector<ll>> dp;
set<ll> st;
void dfs1(ll now, ll depth) {
  if (depth == max(0LL, (ll)(log2(n) / 2) - 1)) {
    st.insert(now);
    return;
  }

  dfs1(now * 2 + 1, depth + 1);
  dfs1(now * 2 + 2, depth + 1);
}
int main(void) {
  cin >> n;
  v.resize(n + 1);
  w.resize(n + 1);
  dp.resize(551, vector<ll>(1e5 + 1, 0));

  for (ll i = 1; i < n + 1; i++) {
    cin >> v[i] >> w[i];
  }

  dp[0][0] = 0;
  for (ll i = 1; i <= min(n, 550LL); i++) {
    for (ll j = 0; j <= 1e5; j++) {
      ll past = (i) / 2;
      if (j + w[i] <= 1e5)
        dp[i][j + w[i]] = max(dp[i][j + w[i]], dp[past][j] + v[i]);
      dp[i][j] = max(dp[i][j], dp[past][j]);
    }
  }

  // dfs1(0, 0);
  // cout << log2(262143) << endl;

  ll q;
  cin >> q;
  vector<ll> an;
  rep(i, q) {
    ll u, l;
    cin >> u >> l;
    ll now = u;
    ll ans = 0;
    vector<pair<ll, ll>> items;
    if (u < pow(2, 9)) {
      ans = dp[now][l];
      an.push_back(ans);
      continue;
    }
    while (now >= pow(2, 9)) {
      items.push_back({v[now], w[now]});
      now = (now) / 2;
      cout << now << endl;
    }

    cout << items.size() << endl;

    for (ll bit = 0; bit < (1LL << (ll)items.size()); bit++) {
      ll sumv = 0;
      ll sumw = 0;
      rep(j, items.size()) {
        if (bit & (1LL << j)) {
          sumv += items[j].first;
          sumw += items[j].second;
        }
      }
      if (now >= 550) {
        cout << "e" << endl;
      }
      if (sumw > l)
        continue;
      ans = max(ans, sumv + dp[now][max(0LL, l - sumw)]);
    }
    an.push_back(ans);
  }
  // cout << "f" << dp[0][2] << endl;
  rep(i, an.size()) { cout << an[i] << endl; }
}