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


#include <algorithm>
#include <chrono>
#include <deque>
#include <fstream>
#include <functional>
#include <iostream>
#include <iterator>
#include <limits>
#include <map>
#include <math.h>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#define forr(i, start, count) for (int i = (start); i < (start) + (count); ++i)
#define set_map_includes(set, elt) (set.find((elt)) != set.end())
#define readint(i)                                                             \\
  int i;                                                                       \\
  cin >> i
#define readll(i)                                                              \\
  ll i;                                                                        \\
  cin >> i
#define readdouble(i)                                                          \\
  double i;                                                                    \\
  cin >> i
#define readstring(s)                                                          \\
  string s;                                                                    \\
  cin >> s

typedef long long ll;

using namespace std;

template <class T> T fastpower(T a, long long n) { // n must be >= 1
  if (n % 2 == 0) {
    T halfpower = fastpower<T>(a, n / 2);
    return halfpower * halfpower;
  } else {
    if (n == 1) {
      return a;
    } else {
      T halfpower = fastpower<T>(a, n / 2);
      return (halfpower * halfpower) * a;
    }
  }
};

int main() {
  cout.precision(17);
  ll modd = 1000 * 1000 * 1000 + 7;
  mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
  uniform_int_distribution<int> rand_gen(
      0, modd); // rand_gen(rng) gets the rand no
  ll infinit = 10000000000000000;

  //    auto start = chrono::steady_clock::now();

  //    readint(test_cases);
  int test_cases = 1;
  int lmax = 100001;
  forr(t, 1, test_cases) {
    readll(n);
    vector<int> val;
    vector<int> wei;
    forr(i, 0, n) {
      readint(vv);
      readint(ww);
      val.push_back(vv);
      wei.push_back(ww);
    }
    readint(q);
    vector<pair<ll, int>> qu;
    forr(i, 0, q) {
      readll(vv);
      readint(lll);
      qu.push_back(make_pair(vv, lll));
      ll curr = vv;
    }

    vector<vector<ll>> memo(513, vector<ll>(lmax, 0));
    forr(w, 0, lmax) { memo[1][w] = (w < wei[0] ? 0 : val[0]); }
    forr(v_, 1, 512) {
      if ((v_ > 1) && (v_ <= n)) {
        ll v_par = v_ / 2;
        forr(w, 0, lmax) {
          memo[v_][w] = (w < wei[v_ - 1]
                             ? memo[v_par][w]
                             : max(memo[v_par][w],
                                   memo[v_par][w - wei[v_ - 1]] + val[v_ - 1]));
        }
      }
    }
    for (auto q : qu) {
      vector<ll> verts;
      ll curr = q.first;
      while (curr > 512) {
        verts.push_back(curr);
        curr /= 2;
      }
      if (verts.empty()) {
        cout << memo[curr][q.second] << endl;
      } else {
        ll w_max = q.second;
        ll max_val = 0;
        int ppp = fastpower<ll>(2, verts.size());
        forr(i, 0, ppp) {
          int kk = i;
          ll total_w = 0, total_val = 0, i_ = 0;
          while (kk > 0) {
            if (kk % 2 == 1) {
              total_w += wei[verts[i_] - 1];
              total_val += val[verts[i_] - 1];
            }
            kk /= 2;
            i_++;
          }
          if (w_max >= total_w) {
            max_val = max(max_val, total_val + memo[curr][w_max - total_w]);
          }
        }
        cout << max_val << endl;
      }
    }
  }

  //    auto end = chrono::steady_clock::now();
  //    cout << chrono::duration_cast<chrono::milliseconds>(end - start).count()
  //    << endl;

  return 0;
}

Error: TLE

Fixed submission:


#include <algorithm>
#include <chrono>
#include <deque>
#include <fstream>
#include <functional>
#include <iostream>
#include <iterator>
#include <limits>
#include <map>
#include <math.h>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#define forr(i, start, count) for (int i = (start); i < (start) + (count); ++i)
#define set_map_includes(set, elt) (set.find((elt)) != set.end())
#define readint(i)                                                             \\
  int i;                                                                       \\
  cin >> i
#define readll(i)                                                              \\
  ll i;                                                                        \\
  cin >> i
#define readdouble(i)                                                          \\
  double i;                                                                    \\
  cin >> i
#define readstring(s)                                                          \\
  string s;                                                                    \\
  cin >> s

typedef long long ll;

using namespace std;

template <class T> T fastpower(T a, long long n) { // n must be >= 1
  if (n % 2 == 0) {
    T halfpower = fastpower<T>(a, n / 2);
    return halfpower * halfpower;
  } else {
    if (n == 1) {
      return a;
    } else {
      T halfpower = fastpower<T>(a, n / 2);
      return (halfpower * halfpower) * a;
    }
  }
};

int main() {
  cout.precision(17);
  ll modd = 1000 * 1000 * 1000 + 7;
  mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
  uniform_int_distribution<int> rand_gen(
      0, modd); // rand_gen(rng) gets the rand no
  ll infinit = 10000000000000000;

  //    auto start = chrono::steady_clock::now();

  //    readint(test_cases);
  int test_cases = 1;
  int lmax = 100001;
  forr(t, 1, test_cases) {
    readll(n);
    vector<int> val;
    vector<int> wei;
    forr(i, 0, n) {
      readint(vv);
      readint(ww);
      val.push_back(vv);
      wei.push_back(ww);
    }
    readint(q);
    vector<pair<ll, int>> qu;
    forr(i, 0, q) {
      readll(vv);
      readint(lll);
      qu.push_back(make_pair(vv, lll));
      ll curr = vv;
    }

    vector<vector<ll>> memo(513, vector<ll>(lmax, 0));
    forr(w, 0, lmax) { memo[1][w] = (w < wei[0] ? 0 : val[0]); }
    forr(v_, 1, 512) {
      if ((v_ > 1) && (v_ <= n)) {
        ll v_par = v_ / 2;
        forr(w, 0, lmax) {
          memo[v_][w] = (w < wei[v_ - 1]
                             ? memo[v_par][w]
                             : max(memo[v_par][w],
                                   memo[v_par][w - wei[v_ - 1]] + val[v_ - 1]));
        }
      }
    }
    for (auto q : qu) {
      vector<ll> verts;
      ll curr = q.first;
      while (curr > 512) {
        verts.push_back(curr);
        curr /= 2;
      }
      if (verts.empty()) {
        cout << memo[curr][q.second] << endl;
      } else {
        ll w_max = q.second;
        ll max_val = 0;
        forr(i, 0, fastpower<ll>(2, verts.size())) {
          int kk = i;
          ll total_w = 0, total_val = 0, i_ = 0;
          while (kk > 0) {
            if (kk % 2 == 1) {
              total_w += wei[verts[i_] - 1];
              total_val += val[verts[i_] - 1];
            }
            kk /= 2;
            i_++;
          }
          if (w_max >= total_w) {
            max_val = max(max_val, total_val + memo[curr][w_max - total_w]);
          }
        }
        cout << max_val << endl;
      }
    }
  }

  //    auto end = chrono::steady_clock::now();
  //    cout << chrono::duration_cast<chrono::milliseconds>(end - start).count()
  //    << endl;

  return 0;
}