#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using pl = pair<ll,ll>;
using pii = pair<int,int>;
using tpl = tuple<int,int,int>;
#define all(a) a.begin(), a.end()
#define filter(a) a.erase(unique(all(a)), a.end())
const int mn = 2e5 + 5;
ll energy[mn], cost[mn], sq[mn], tq[mn], uq[mn], ans[mn], spare[mn];
int n, Q;
namespace processSpare {
    struct IT {
        vector<ll> cnt, sum;
        IT (int sz) : cnt(sz << 2), sum(sz << 2) {}
        void update (int pos, ll val, int k, int l, int r) {
            while (l < r) {
                int mid = (l + r) >> 1;
                if (pos <= mid) k <<= 1, r = mid;
                else k <<= 1, k |= 1, l = mid + 1;
            }
            cnt[k] += val, sum[k] += val * cost[pos];
            for (k >>= 1; k >= 1; k >>= 1) {
                cnt[k] = cnt[k << 1] + cnt[k << 1 | 1];
                sum[k] = sum[k << 1] + sum[k << 1 | 1];
            }
        }
        ll del (int pos, int k, int l, int r) {
            while (l < r) {
                int mid = (l + r) >> 1;
                if (pos <= mid) k <<= 1, r = mid;
                else k <<= 1, k |= 1, l = mid + 1;
            }
            ll ans = cnt[k];
            cnt[k] = sum[k] = 0;
            for (k >>= 1; k >= 1; k >>= 1) {
                cnt[k] = cnt[k << 1] + cnt[k << 1 | 1];
                sum[k] = sum[k << 1] + sum[k << 1 | 1];
            }
            return ans;
        }
        ll walk (ll need, int k, int l, int r) {
            ll ans = 0;
            while (l < r) {
                int mid = (l + r) >> 1;
                if (cnt[k << 1] >= need) k <<= 1, r = mid;
                else {
                    ans += sum[k << 1], need -= cnt[k << 1];
                    k <<= 1, k |= 1, l = mid + 1;
                }
            }
            return ans += need * cost[l];
        }
    };
    vector<int> pr[mn];
    void process() {
        for (int i = 0; i < Q; i++)
            if (ans[i] != -1) pr[sq[i]].push_back(i);
        IT tree(n); stack<int> st;
        for (int i = n; i >= 1; i--) {
            ll block = energy[i];
            while (st.size() && cost[i] <= cost[st.top()])
                block += tree.del(st.top(), 1, 1, n), st.pop();
            tree.update(i, block, 1, 1, n), st.push(i);
            for (int u : pr[i])
                ans[u] += tree.walk(spare[u], 1, 1, n);
        }
    }
};
namespace brute {
    ll solve (int l, int r, int U) {
        map<ll,ll> mp;
        vector<int> erased;
        ll sumCands = 0, ans = 0;
        for (int i = l; i <= r; i++) {
            if (energy[i] > U) return -1;
            mp[cost[i]] += U, sumCands += U;
            for (auto it = mp.rbegin(); it != mp.rend() && sumCands > U; it++) {
                ll subtract = min(it->second, sumCands - U);
                sumCands -= subtract, it->second -= subtract;
                if (!it->second) erased.push_back(it->first);
            }
            for (int u : erased) mp.erase(u);
            erased.clear();
            ll used = energy[i];
            for (auto it = mp.begin(); it != mp.end() && used > 0; it++) {
                ll subtract = min(it->second, used);
                used -= subtract, it->second -= subtract, sumCands -= subtract;
                ans += 1LL * it->first * subtract;
                if (!it->second) erased.push_back(it->first);
            }
            for (int u : erased) mp.erase(u);
            erased.clear();
        }
        return ans;
    }
    void solve() {
        for (int i = 0; i < Q; i++) {
            if (ans[i] == -1) cout << -1 << "\n";
            else cout << solve(sq[i], tq[i] - 1, uq[i]) << "\n";
        }
    }
    bool check() { return 1; }
}
namespace sameU {
    ll pre[mn], preLen[mn], preCost[mn];
    ll block[mn], U;
    void solve() {
        /// compute block sizes
        block[1] = U;
        stack<int> st; st.push(1); // maintain non-empty blocks
        for (int i = 2; i <= n; i++) {
            block[i] = energy[i - 1];
            ll spare = U - energy[i - 1];
            while (spare && st.size() && cost[st.top()] > cost[i]) {
                ll take = min(spare, block[st.top()]);
                spare -= take, block[st.top()] -= take, block[i] += take;
                if (!block[st.top()]) st.pop();
            }
            st.push(i);
        }
//        for (int i = 1; i <= n; i++) cout << block[i] << " ";
//        cout << "\n";
        /// prefix sums
        for (int i = 1; i <= n; i++) {
            pre[i] = pre[i - 1] + energy[i];
            preLen[i] = preLen[i - 1] + block[i];
            preCost[i] = preCost[i - 1] + block[i] * cost[i];
        }
        /// process queries
        for (int i = 0; i < Q; i++) {
            if (ans[i] == -1) continue;
            ll L = sq[i], R = tq[i] - 1;
            int stopBlock = lower_bound(preLen, preLen + 1 + n, pre[R]) - preLen;
            if (L <= stopBlock) {
                ans[i] = preCost[stopBlock] - preCost[L - 1] - (preLen[stopBlock] - pre[R]) * cost[stopBlock];
                spare[i] = preLen[L - 1] - pre[L - 1];
            }
            else spare[i] = pre[R] - pre[L - 1];
//            cout << "query " << i << " " << ans[i] << " " << spare[i] << "\n";
        }
        /// process spare
        processSpare::process();
        for (int i = 0; i < Q; i++) cout << ans[i] << "\n";
    }
    bool check() {
        U = uq[0];
        for (int i = 1; i < Q; i++)
            if (uq[i] != U) return 0;
        return 1;
    }
};
int spt[mn][21];
int query (int l, int r) {
    int p = 31 - __builtin_clz(r - l + 1);
    return max(spt[l][p], spt[r - (1 << p) + 1][p]);
}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    /// input
    cin >> n >> Q;
    for (int i = 1; i <= n; i++) {
        cin >> energy[i];
        spt[i][0] = energy[i];
    }
    for (int i = 1; i <= n; i++) cin >> cost[i];
    for (int i = 0; i < Q; i++)
        cin >> sq[i] >> tq[i] >> uq[i];
    /// process invalid queries
    for (int s = 1; (1 << s) <= n; s++) {
        for (int i = 1; i <= n; i++) {
            int p = s - 1;
            spt[i][s] = max(spt[i][p], spt[i + (1 << p)][p]);
        }
    }
    for (int i = 0; i < Q; i++)
        if (query(sq[i], tq[i] - 1) > uq[i]) ans[i] = -1;
    if (sameU::check()) return sameU::solve(), 0;
//    if (brute::check()) return brute::solve(), 0;
    return 0;
}
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... |