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


// Problem : D - Knapsack Queries on a tree
// Contest : AtCoder - Tokio Marine & Nichido Fire Insurance Programming Contest
// 2020 URL :
// https://atcoder.jp/contests/tokiomarine2020/tasks/tokiomarine2020_d Memory
// Limit : 1024 MB Time Limit : 3000 ms Powered by CP Editor
// (https://github.com/cpeditor/cpeditor)

#include <bits/stdc++.h>
using namespace std;
#define flush cin.ignore(numeric_limits<streamsize>::max(), '\\n')
#define fill(w, t) memset(w, t, sizeof(w))
#define google cout << "Case #" << countu << ": "
#define S(t) (ll) t.size()
#define bl '\\n'
#define nl cout << bl
#define cout1(a) cout << a << bl
#define cout2(a, b) cout << a << " " << b << bl
#define cout3(a, b, c) cout << a << " " << b << " " << c << bl
#define cout4(a, b, c, d) cout << a << " " << b << " " << c << " " << d << bl
#define print(a, s, e)                                                         \\
  for (ll i = s; i <= e; i++) {                                                \\
    cout << a[i] << " ";                                                       \\
  }
#define rprint(a, s, e)                                                        \\
  for (ll i = s; i >= e; i--) {                                                \\
    cout << a[i] << " ";                                                       \\
  }
#define input(a, s, e) sfor(p, s, e) cin >> a[p]
#define all(v) v.begin(), v.end()
#define ll long long
#define ldb long double
#define db double
#define ull unsigned long long
#define lb lower_bound
#define ub upper_bound
#define pb push_back
#define mk make_pair
#define pll pair<ll, ll>
#define pldb pair<ldb, ldb>
#define fi first
#define se second
#define vull vector<ull>
#define vll vector<ll>
#define vldb vector<ldb>
#define vpll vector<pll>
#define vpldb vector<pldb>
#define pqmin priority_queue<ll, vector<ll>, greater<ll>>       // minheap
#define pq priority_queue<ll>                                   // maxheap ll
#define pqpll priority_queue<pll>                               // maxheap pll
#define pqpllmin priority_queue<pll, vector<pll>, greater<pll>> // minheap pll
#define mll map<ll, ll>
#define mldb map<ldb, ldb>
#define umll unordered_map<ll, ll>
#define sll set<ll>
#define usll unordered_set<ll>
#define sfor(i, a, b) for (ll i = (a); i <= (b); ++i)
#define rfor(i, b, a) for (ll i = (b); i >= (a); --i)
const ll mod = 1e9 + 7;
const ll maxn = 1e6 + 1;
const ll llmax = (1ll << 60);
const int intmax = (1 << 30);
const ldb PI =
    3.14159265358979323846264338327950288419716939937510582097494459230781640628620899863;
ll *fact, *ifact;
vll primes;
ll *spf;
void sieve() {
  spf = new ll[maxn + 1];
  fill(spf, 0);
  spf[0] = 0;
  spf[1] = 1;
  for (ll i = 2; i <= maxn; i++) {
    if (spf[i])
      continue;
    spf[i] = i;
    for (ll j = i * i; j <= maxn; j += i) {
      if (spf[j] == 0)
        spf[j] = i;
    }
  }
  for (ll p = 2; p <= maxn; p++)
    if (spf[p] == p)
      primes.pb(p);
}
vll primes1;
void sieve2(ll l, ll r) {
  bool isprime[r - l + 1];
  fill(isprime, 1);
  if (l == 1)
    isprime[0] = false;
  ll base;
  for (ll i = 0; primes[i] * primes[i] <= r; i++) {
    base = (l / primes[i]) * primes[i];
    if (base < l) {
      base += primes[i];
    }
    for (long long j = base; j <= r; j += primes[i]) {
      isprime[j - l] = false;
    }
    if (base == primes[i]) {
      isprime[base - l] = true;
    }
  }
  for (int i = 0; i < r - l + 1; i++) {
    if (isprime[i])
      primes1.pb(i + l);
  }
}
// void primefactorization(ll x,mll &mp)
// {
//      for(ll i=0;primes[i]*primes[i]<=x;i++)
//     {
//         while(x%primes[i]==0)
//         {
//             mp[primes[i]]++;
//             x/=primes[i];
//         }
//     }
//     if(x!=1)
//     {
//         mp[x]++;
//     }
// }
void primefactorization(ll n, mll &mp) {
  while (n != 1) {
    mp[spf[n]]++;
    n /= spf[n];
  }
}

bool primeornot(ll n) {
  for (ll i = 0; primes[i] * primes[i] <= n; i++) {
    if (n % primes[i] == 0) {
      return false;
    }
  }
  return true;
}

void allfactors(vll &v, ll n) {
  for (ll i = 1; i * i <= n; i++) {
    if (n % i == 0) {
      v.pb(i);
      if (i * i != n) {
        v.pb(n / i);
      }
    }
  }
  sort(v.begin(), v.end());
}

ll power(ll a, ll n) {
  ll res = 1;
  while (n) {
    if (n % 2) {
      res = ((res % mod) * (a % mod)) % mod;
    }
    a = ((a % mod) * (a % mod)) % mod;
    n /= 2;
  }
  res %= mod;
  return res;
}

ll modInv(ll a) { return power(a, mod - 2) % mod; }

void modFact() {
  ll n = maxn;
  ifact = new ll[n + 1];
  fact = new ll[n + 1];
  fact[0] = fact[1] = 1;
  for (int i = 2; i <= n; i++) {
    fact[i] = (i * fact[i - 1]) % mod;
  }
  ifact[n] = modInv(fact[n]);
  for (int i = n - 1; i >= 0; i--) {
    ifact[i] = ((i + 1) * ifact[i + 1]) % mod;
  }
}

ll ncr(ll n, ll r) {
  if (n < r || r < 0)
    return 0;
  ll ans = fact[n];
  ans *= ifact[r];
  ans %= mod;
  ans *= ifact[n - r];
  ans %= mod;
  return ans;
}

ll npr(ll n, ll r) {
  if (n < r || r < 0)
    return 0;
  ll ans = fact[n];
  ans *= ifact[n - r];
  return ans % mod;
}

ll lcm(ll a, ll b) {
  ll x = __gcd(a, b);
  a /= x;
  b /= x;
  ll sum = a * b * x;
  return sum;
}

bool ispalindrome(string str, ll l, ll r) {
  while (l <= r) {
    if (str[l] != str[r])
      return false;
    l++;
    r--;
  }
  return true;
}

ll reversenum(ll n) {
  ll ans = 0;
  while (n) {
    ans = (ans * 10) + n % 10;
    n /= 10;
  }
  return ans;
}

void fraction(string &str, ll &num, ll &den) {
  ll n = str.length();
  ll count_after_dot = 0;
  bool dot_seen = false;

  for (ll i = 0; i < n; i++) {
    if (str[i] != '.') {
      num = num * 10 + (str[i] - '0');
      if (dot_seen == true)
        count_after_dot++;
    } else
      dot_seen = true;
  }
  if (dot_seen == false) {
    den = 1;
    return;
  }
  ll dem = (ll)pow(10, count_after_dot);
  ll g = __gcd(num, dem);
  num = num / g;
  den = dem / g;
  return;
}

string convert_to_bit(ll a, int bit) {
  string s;
  while (a > 0) {
    s += (a % 2) + 48;
    a /= 2;
  }
  while (s.size() < bit)
    s += '0';
  reverse(s.begin(), s.end());
  return s;
}

string tobinary(ll n) {
  if (n == 0)
    return "0";
  else if (n == 1)
    return "1";
  else if (n % 2 == 0)
    return tobinary(n / 2) + "0";
  else if (n % 2 != 0)
    return tobinary(n / 2) + "1";
}
#define countsetbit __builtin_popcount

ll countbit(ll n) { return (ll)log2(n) + 1; }

ll setbit(ll n, ll k) { return (n | (1 << (k - 1))); }

ll clearbit(ll n, ll k) { return (n & (~(1 << (k - 1)))); }

ll togglebit(ll n, ll k) { return (n ^ (1 << (k - 1))); }
// ifstream cin("b_read_on.txt"); ofstream cout("output3.txt");
// Use (<<) for multiplication
// Use (>>) for division
// ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);cout<<fixed;cerr.tie(NULL);
//  find_by_order -> value at index
//  order_of_key -> index of value
//  while using (1<<i) use ((ll)1<<(ll)i)
//  in Floyd-Warshall Algo, k is outer loop
//  If an element was not initially in map and if asked mp[a],the element gets
//  inserted a%=mod take a lot of time... try to use it minimum and use memset
//  as it reduces a lot of time usage...use if(a>=mod) a%=mod
// cout<<(double) can be harmful , always use printf(%.9llf)...take
// scanf("%lf",&p[i][j]) as input , not llf; use s.erase(it++) for erasing
// iterator and then moving to the next one never use adj.resize(n) as value is
// persistent, always erase use __builtin_popcountll() for ll
//  no of prime numbers in range : (70,19) , (1000,168) , (100000,1229) ,
//  (sqrt(10^9),3409) ;
// always check the use of segment tree using bottom-up dp
const ll lmt = 1e5;
const ll mx = 511;
ll K[mx + 1][lmt + 1];
vpll temp;
ll ans;
void fun(vpll &v, ll sz) {
  sfor(i, 1, sz) {
    sfor(j, 1, lmt) {
      if (v[i].se <= j) {
        K[i][j] = max(v[i].fi + K[i / 2][j - v[i].se], K[i / 2][j]);
      } else {
        K[i][j] = K[i / 2][j];
      }
    }
  }
}

void fun(ll pos, ll w, ll sz, ll val, ll gp) {
  if (w < 0) {
    return;
  }
  if (pos == sz) {
    ans = max(ans, val + K[gp][w]);
    return;
  }
  ans = max(ans, val);
  fun(pos + 1, w, sz, val, gp);
  fun(pos + 1, w - temp[pos].se, sz, val + temp[pos].fi, gp);
}

void solve(ll countu) {
  ll n;
  cin >> n;
  vpll v(n + 1);
  sfor(i, 1, n) { cin >> v[i].fi >> v[i].se; }
  fun(v, min(n, 511LL));
  ll q;
  cin >> q;
  while (q--) {
    ll x, w;
    cin >> x >> w;
    if (x < 512) {
      cout << K[x][w] << bl;
      continue;
    }
    temp.clear();
    ans = 0;
    while (x && x > 511) {
      temp.pb(v[x]);
      x /= 2;
    }

    fun(0, w, S(temp), 0, x);
    // ll sz = S(temp);
    // ll T[sz+1][w+1];
    // sfor(i,0,sz)
    // {
    // sfor(j,0,w)
    // {
    // if(i==0)
    // {
    // T[i][j] = K[x][j];
    // }
    // else if(j==0)
    // {
    // T[i][j] = 0;
    // }
    // else if(temp[i-1].se<=j)
    // {
    // T[i][j] = max(temp[i-1].fi+T[i-1][j-temp[i-1].se],T[i-1][j]);
    // }
    // else
    // {
    // T[i][j] = T[i-1][j];
    // }
    // }
    // }
    cout << ans << bl;
  }
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  srand(time(0));

  ll t = 1;
  // cin>>t;
  sfor(i, 1, t) solve(i);

  return 0;
}


Error: TLE

Fixed submission:


// Problem : D - Knapsack Queries on a tree
// Contest : AtCoder - Tokio Marine & Nichido Fire Insurance Programming Contest
// 2020 URL :
// https://atcoder.jp/contests/tokiomarine2020/tasks/tokiomarine2020_d Memory
// Limit : 1024 MB Time Limit : 3000 ms Powered by CP Editor
// (https://github.com/cpeditor/cpeditor)

#include <bits/stdc++.h>
using namespace std;
#define flush cin.ignore(numeric_limits<streamsize>::max(), '\\n')
#define fill(w, t) memset(w, t, sizeof(w))
#define google cout << "Case #" << countu << ": "
#define S(t) (ll) t.size()
#define bl '\\n'
#define nl cout << bl
#define cout1(a) cout << a << bl
#define cout2(a, b) cout << a << " " << b << bl
#define cout3(a, b, c) cout << a << " " << b << " " << c << bl
#define cout4(a, b, c, d) cout << a << " " << b << " " << c << " " << d << bl
#define print(a, s, e)                                                         \\
  for (ll i = s; i <= e; i++) {                                                \\
    cout << a[i] << " ";                                                       \\
  }
#define rprint(a, s, e)                                                        \\
  for (ll i = s; i >= e; i--) {                                                \\
    cout << a[i] << " ";                                                       \\
  }
#define input(a, s, e) sfor(p, s, e) cin >> a[p]
#define all(v) v.begin(), v.end()
#define ll long long
#define ldb long double
#define db double
#define ull unsigned long long
#define lb lower_bound
#define ub upper_bound
#define pb push_back
#define mk make_pair
#define pll pair<ll, ll>
#define pldb pair<ldb, ldb>
#define fi first
#define se second
#define vull vector<ull>
#define vll vector<ll>
#define vldb vector<ldb>
#define vpll vector<pll>
#define vpldb vector<pldb>
#define pqmin priority_queue<ll, vector<ll>, greater<ll>>       // minheap
#define pq priority_queue<ll>                                   // maxheap ll
#define pqpll priority_queue<pll>                               // maxheap pll
#define pqpllmin priority_queue<pll, vector<pll>, greater<pll>> // minheap pll
#define mll map<ll, ll>
#define mldb map<ldb, ldb>
#define umll unordered_map<ll, ll>
#define sll set<ll>
#define usll unordered_set<ll>
#define sfor(i, a, b) for (ll i = (a); i <= (b); ++i)
#define rfor(i, b, a) for (ll i = (b); i >= (a); --i)
const ll mod = 1e9 + 7;
const ll maxn = 1e6 + 1;
const ll llmax = (1ll << 60);
const int intmax = (1 << 30);
const ldb PI =
    3.14159265358979323846264338327950288419716939937510582097494459230781640628620899863;
ll *fact, *ifact;
vll primes;
ll *spf;
void sieve() {
  spf = new ll[maxn + 1];
  fill(spf, 0);
  spf[0] = 0;
  spf[1] = 1;
  for (ll i = 2; i <= maxn; i++) {
    if (spf[i])
      continue;
    spf[i] = i;
    for (ll j = i * i; j <= maxn; j += i) {
      if (spf[j] == 0)
        spf[j] = i;
    }
  }
  for (ll p = 2; p <= maxn; p++)
    if (spf[p] == p)
      primes.pb(p);
}
vll primes1;
void sieve2(ll l, ll r) {
  bool isprime[r - l + 1];
  fill(isprime, 1);
  if (l == 1)
    isprime[0] = false;
  ll base;
  for (ll i = 0; primes[i] * primes[i] <= r; i++) {
    base = (l / primes[i]) * primes[i];
    if (base < l) {
      base += primes[i];
    }
    for (long long j = base; j <= r; j += primes[i]) {
      isprime[j - l] = false;
    }
    if (base == primes[i]) {
      isprime[base - l] = true;
    }
  }
  for (int i = 0; i < r - l + 1; i++) {
    if (isprime[i])
      primes1.pb(i + l);
  }
}
// void primefactorization(ll x,mll &mp)
// {
//      for(ll i=0;primes[i]*primes[i]<=x;i++)
//     {
//         while(x%primes[i]==0)
//         {
//             mp[primes[i]]++;
//             x/=primes[i];
//         }
//     }
//     if(x!=1)
//     {
//         mp[x]++;
//     }
// }
void primefactorization(ll n, mll &mp) {
  while (n != 1) {
    mp[spf[n]]++;
    n /= spf[n];
  }
}

bool primeornot(ll n) {
  for (ll i = 0; primes[i] * primes[i] <= n; i++) {
    if (n % primes[i] == 0) {
      return false;
    }
  }
  return true;
}

void allfactors(vll &v, ll n) {
  for (ll i = 1; i * i <= n; i++) {
    if (n % i == 0) {
      v.pb(i);
      if (i * i != n) {
        v.pb(n / i);
      }
    }
  }
  sort(v.begin(), v.end());
}

ll power(ll a, ll n) {
  ll res = 1;
  while (n) {
    if (n % 2) {
      res = ((res % mod) * (a % mod)) % mod;
    }
    a = ((a % mod) * (a % mod)) % mod;
    n /= 2;
  }
  res %= mod;
  return res;
}

ll modInv(ll a) { return power(a, mod - 2) % mod; }

void modFact() {
  ll n = maxn;
  ifact = new ll[n + 1];
  fact = new ll[n + 1];
  fact[0] = fact[1] = 1;
  for (int i = 2; i <= n; i++) {
    fact[i] = (i * fact[i - 1]) % mod;
  }
  ifact[n] = modInv(fact[n]);
  for (int i = n - 1; i >= 0; i--) {
    ifact[i] = ((i + 1) * ifact[i + 1]) % mod;
  }
}

ll ncr(ll n, ll r) {
  if (n < r || r < 0)
    return 0;
  ll ans = fact[n];
  ans *= ifact[r];
  ans %= mod;
  ans *= ifact[n - r];
  ans %= mod;
  return ans;
}

ll npr(ll n, ll r) {
  if (n < r || r < 0)
    return 0;
  ll ans = fact[n];
  ans *= ifact[n - r];
  return ans % mod;
}

ll lcm(ll a, ll b) {
  ll x = __gcd(a, b);
  a /= x;
  b /= x;
  ll sum = a * b * x;
  return sum;
}

bool ispalindrome(string str, ll l, ll r) {
  while (l <= r) {
    if (str[l] != str[r])
      return false;
    l++;
    r--;
  }
  return true;
}

ll reversenum(ll n) {
  ll ans = 0;
  while (n) {
    ans = (ans * 10) + n % 10;
    n /= 10;
  }
  return ans;
}

void fraction(string &str, ll &num, ll &den) {
  ll n = str.length();
  ll count_after_dot = 0;
  bool dot_seen = false;

  for (ll i = 0; i < n; i++) {
    if (str[i] != '.') {
      num = num * 10 + (str[i] - '0');
      if (dot_seen == true)
        count_after_dot++;
    } else
      dot_seen = true;
  }
  if (dot_seen == false) {
    den = 1;
    return;
  }
  ll dem = (ll)pow(10, count_after_dot);
  ll g = __gcd(num, dem);
  num = num / g;
  den = dem / g;
  return;
}

string convert_to_bit(ll a, int bit) {
  string s;
  while (a > 0) {
    s += (a % 2) + 48;
    a /= 2;
  }
  while (s.size() < bit)
    s += '0';
  reverse(s.begin(), s.end());
  return s;
}

string tobinary(ll n) {
  if (n == 0)
    return "0";
  else if (n == 1)
    return "1";
  else if (n % 2 == 0)
    return tobinary(n / 2) + "0";
  else if (n % 2 != 0)
    return tobinary(n / 2) + "1";
}
#define countsetbit __builtin_popcount

ll countbit(ll n) { return (ll)log2(n) + 1; }

ll setbit(ll n, ll k) { return (n | (1 << (k - 1))); }

ll clearbit(ll n, ll k) { return (n & (~(1 << (k - 1)))); }

ll togglebit(ll n, ll k) { return (n ^ (1 << (k - 1))); }
// ifstream cin("b_read_on.txt"); ofstream cout("output3.txt");
// Use (<<) for multiplication
// Use (>>) for division
// ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);cout<<fixed;cerr.tie(NULL);
//  find_by_order -> value at index
//  order_of_key -> index of value
//  while using (1<<i) use ((ll)1<<(ll)i)
//  in Floyd-Warshall Algo, k is outer loop
//  If an element was not initially in map and if asked mp[a],the element gets
//  inserted a%=mod take a lot of time... try to use it minimum and use memset
//  as it reduces a lot of time usage...use if(a>=mod) a%=mod
// cout<<(double) can be harmful , always use printf(%.9llf)...take
// scanf("%lf",&p[i][j]) as input , not llf; use s.erase(it++) for erasing
// iterator and then moving to the next one never use adj.resize(n) as value is
// persistent, always erase use __builtin_popcountll() for ll
//  no of prime numbers in range : (70,19) , (1000,168) , (100000,1229) ,
//  (sqrt(10^9),3409) ;
// always check the use of segment tree using bottom-up dp
const ll lmt = 1e5;
const ll mx = 511;
ll K[mx + 1][lmt + 1];
void fun(vpll &v, ll sz) {
  sfor(i, 1, sz) {
    sfor(j, 1, lmt) {
      if (v[i].se <= j) {
        K[i][j] = max(v[i].fi + K[i / 2][j - v[i].se], K[i / 2][j]);
      } else {
        K[i][j] = K[i / 2][j];
      }
    }
  }
}
void solve(ll countu) {
  ll n;
  cin >> n;
  vpll v(n + 1);
  sfor(i, 1, n) { cin >> v[i].fi >> v[i].se; }
  fun(v, min(n, 511LL));
  ll q;
  cin >> q;
  while (q--) {
    ll x, w;
    cin >> x >> w;
    vpll temp;
    while (x && x > 511) {
      temp.pb(v[x]);
      x /= 2;
    }
    ll sz = S(temp);
    ll T[sz + 1][w + 1];
    sfor(i, 0, sz) {
      sfor(j, 0, w) {
        if (i == 0) {
          T[i][j] = K[x][j];
        } else if (j == 0) {
          T[i][j] = 0;
        } else if (temp[i - 1].se <= j) {
          T[i][j] =
              max(temp[i - 1].fi + T[i - 1][j - temp[i - 1].se], T[i - 1][j]);
        } else {
          T[i][j] = T[i - 1][j];
        }
      }
    }
    cout << T[sz][w] << bl;
  }
}

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  srand(time(0));

  ll t = 1;
  // cin>>t;
  sfor(i, 1, t) solve(i);

  return 0;
}