Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #ifdef ENABLE_DEBUG
- #define DEBUG(x) std::cout << x << std::endl
- #else
- #define DEBUG(x)
- #endif
- #define fi first
- #define se second
- #define pb push_back
- #define all(x) x.begin(),x.end()
- #define rall(x) x.rbegin(),x.rend()
- using namespace std;
- using ii = pair<int, int>;
- using iii = tuple<int, int, int>;
- using i64 = long long;
- const int INF = 0x3f3f3f3f;
- const i64 INFLL = 0x3f3f3f3f3f3f3f3fLL;
- const int MAXN = 1e5+5;
- template<class T>
- class SegmentTreeLazy {
- struct Node {
- int idx;
- T val;
- Node(T x, int idx) : val(x), idx(idx) {}
- Node () : val(INFLL), idx(INF) {}
- };
- int N;
- std::vector<T> a, lazy;
- std::vector<Node> tr;
- Node neutral;
- inline Node join(const Node &a, const Node &b) {
- if (a.val < b.val) return Node(a.val, a.idx);
- return Node(b.val, b.idx);
- }
- inline void upLazy(int node, int l, int r) {
- if (lazy[node] == 0) return;
- tr[node].val += lazy[node];
- int lc = (node << 1);
- (l != r ? lazy[lc] += lazy[node], lazy[lc+1] += lazy[node] : 0);
- lazy[node] = 0;
- }
- void build(int node, int l, int r) {
- if (l == r) tr[node] = Node(a[l], l);
- else {
- int mid = l+(r-l)/2, lc = (node << 1);
- build(lc, l, mid);
- build(lc+1, mid+1, r);
- tr[node] = join(tr[lc], tr[lc+1]);
- }
- }
- void update(int node, int l, int r, int ul, int ur, T x) {
- upLazy(node, l, r);
- if (r < r or ur < ul or ur < l or r < ul) return;
- if (ul <= l and r <= ur) {
- lazy[node] += x;
- upLazy(node, l, r);
- } else {
- int mid = l+(r-l)/2, lc = (node << 1);
- update(lc, l, mid, ul, std::min(ur, mid), x);
- update(lc+1, mid+1, r, std::max(mid+1, ul), ur, x);
- tr[node] = join(tr[lc], tr[lc+1]);
- }
- }
- Node query(int node, int l, int r, int ql, int qr) {
- upLazy(node, l, r);
- if (r < l or qr < ql or qr < l or r < ql) return neutral;
- if (ql <= l and r <= qr) return tr[node];
- int mid = l+(r-l)/2, lc = (node << 1);
- return join(query(lc, l, mid, ql, std::min(qr, mid)),
- query(lc+1, mid+1, r, std::max(mid+1, ql), qr));
- }
- public:
- template<class MyIterator>
- SegmentTreeLazy (MyIterator begin, MyIterator end) {
- N = end-begin-1;
- tr.assign(4*N, Node(INFLL, INF));
- lazy.assign(4*N, 0);
- a = std::vector<T>(begin, end);
- build(1, 1, N);
- }
- SegmentTreeLazy (int n) : N(n) {
- tr.assign(4*N, Node(INFLL, n));
- lazy.assign(4*N, 0);
- a.assign(N+1, 0);
- }
- pair<T, int> query(int l, int r) {
- Node res = query(1, 1, N, l, r);
- return ii(res.val, res.idx);
- }
- void update(int l, int r, T x) {
- update(1, 1, N, l, r, x);
- }
- };
- int k;
- class Compare {
- public:
- bool operator()(iii a, iii b) {
- auto [l1, r1, mn1] = a;
- auto [l2, r2, mn2] = b;
- i64 s1 = 1LL * (r1 - l1 + 1) * min(mn1, k);
- i64 s2 = 1LL * (r2 - l2 + 1) * min(mn2, k);
- if (s1 == s2) {
- return (r1 - l1 + 1) < (r2 - l2 + 1);
- }
- return s1 < s2;
- }
- };
- int main() {
- cin.tie(0)->sync_with_stdio(0);
- int n, q;
- cin >> n >> q;
- i64 currSum = 0;
- vector<i64> b{0};
- for (int i = 0; i < n; ++i) {
- int x;
- cin >> x;
- b.pb(x);
- currSum += x;
- }
- SegmentTreeLazy<i64> ST(b.begin(), b.end());
- priority_queue<iii, vector<iii>, Compare> pq;
- auto get_range = [&](auto&& get_range, int l, int r) {
- if (r < l) return;
- auto [val, idx] = ST.query(l, r);
- if (val == 0) {
- get_range(get_range, l, idx-1);
- get_range(get_range, idx+1, r);
- return;
- }
- if (val > 0) {
- pq.push({ l, r, val });
- }
- };
- pq.push({ 1, n, ST.query(1, n).fi });
- while (q--) {
- cin >> k;
- while (k > 0) {
- if (pq.empty()) break;
- auto [l, r, mn] = pq.top(); pq.pop();
- int qtd = min(mn, k);
- currSum -= 1LL * (r - l + 1) * qtd;
- k -= qtd;
- ST.update(l, r, -qtd);
- get_range(get_range, l, r);
- }
- cout << currSum << '\n';
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment