Submission #1369034

#TimeUsernameProblemLanguageResultExecution timeMemory
1369034mannshah1211Fish 3 (JOI24_fish3)C++17
100 / 100
708 ms109480 KiB
// ロンリーガールはいつまでも
// 届かない夢見て
#include <bits/stdc++.h>

using namespace std;

#ifdef LOCAL
#include "algo/debug.h"
#else
#define debug(...) 42
#endif

int main() {
  int n;
  cin >> n;
  long long d;
  cin >> d;
  vector<long long> a(n);
  for (int i = 0; i < n; i++) {
    cin >> a[i];
  }
  vector<long long> x(n - 1);
  for (int i = 0; i < n - 1; i++) {
    if (a[i] - a[i + 1] <= 0) {
      x[i] = -((a[i + 1] - a[i]) / d);                                
    } else {
      x[i] = (a[i] - a[i + 1] + d - 1) / d;
    }
  }
  vector<long long> pref(n);
  for (int i = 1; i < n; i++) {
    pref[i] = pref[i - 1] + x[i - 1];
  }
  vector<vector<int>> prv(n, vector<int>(20, -1));
  stack<pair<long long, int>> st;
  vector<long long> prefpref(n);
  vector<vector<long long>> vals(n, vector<long long>(20));
  for (int i = 1; i < n; i++) {
    prefpref[i] = prefpref[i - 1] + pref[i];
  }
  // in order to calculate for some range [l ... r]
  // we need to find pref[r] - pref[l - 1] + pref[r] - pref[l] + ... + 
  // this is basically [prv[r][j] + 1 ... r]
  // pref[r] - pref[prv[r][j]] + pref[r] - pref[prv[r][j] + 1] + ... + pref[r] - pref[r]
  auto calc = [&](int l, int r) {
    if (l > r) {
      return 0ll;
    }
    long long rn = (static_cast<long long>(r - l + 1) * static_cast<long long>(pref[r]) - prefpref[r - 1]);
    if (l != 1) {
      rn += prefpref[l - 2];
    }
    return rn;
  };
  for (int i = 0; i < n; i++) {
    while (!st.empty() && st.top().first <= pref[i]) {
      st.pop();
    }
    if (!st.empty()) {
      prv[i][0] = st.top().second;
    }
    if (prv[i][0] != -1) {
      vals[i][0] = calc(prv[i][0] + 2, i);
    }
    st.push(make_pair(pref[i], i));
  }
  for (int j = 1; j < 20; j++) {
    for (int i = 0; i < n; i++) {
      if (prv[i][j - 1] == -1) {
        prv[i][j] = -1;
      } else {
        prv[i][j] = prv[prv[i][j - 1]][j - 1];
        vals[i][j] = vals[i][j - 1] + vals[prv[i][j - 1]][j - 1];
      }
    }
  }
  int q;
  cin >> q;
  for (int qq = 0; qq < q; qq++) {
    int l, r;
    cin >> l >> r;
    // start from r - 1, and go till l
    // till when do you have >= 0 prefix sum?
    if (l == r) {
      cout << 0 << '\n';
      continue;
    }
    long long ans = 0;
    int x = r - 1, xx = -1;
    for (int j = 19; j >= 0; j--) {
      if (prv[x][j] >= l - 1) {
        ans += vals[x][j];
        if (prv[x][j] == l - 1) {
          xx = x;
        }
        x = prv[x][j];
      }
    }
    // if at x, we're 0, what are we at l?
    // pref[x - 1] - pref[l - 1]
    ans += calc(l, x);
    if (static_cast<long long>(pref[x] - pref[l - 1]) * d > a[l - 1]) {
      cout << -1 << '\n';
    } else {
      if (xx != -1 && static_cast<long long>(pref[xx] - pref[l - 1]) * d > a[l - 1]) {
        cout << -1 << '\n';
      } else {
        cout << ans << '\n';
      }
    }
  }
  return 0;
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...