Submission #1307086

#TimeUsernameProblemLanguageResultExecution timeMemory
1307086jwpassion1Weirdtree (RMI21_weirdtree)C++20
0 / 100
298 ms589824 KiB
#include <bits/stdc++.h>
#include "weirdtree.h"
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;

int N, h[300000];

struct Node {
    int max, max2, maxco, max2co;
    ll sum;
}seg[1048576];
int lazy[1048576];

void merge(Node &ret, Node &l, Node &r) {
    if (l.max > r.max) {
        ret.max = l.max;
        ret.maxco = l.maxco;
        if (l.max2 >= r.max) {
            ret.max2 = l.max2;
            ret.max2co = l.max2co;
            if (l.max2 == r.max) ret.max2co += r.maxco;
        }
        else {
            ret.max2 = r.max;
            ret.max2co = r.maxco;
        }
    }
    else if (l.max < r.max) {
        ret.max = r.max;
        ret.maxco = r.maxco;
        if (l.max >= r.max2) {
            ret.max2 = l.max;
            ret.max2co = l.maxco;
            if (l.max == r.max2) ret.max2co += r.max2co;
        }
        else {
            ret.max2 = r.max2;
            ret.max2co = r.max2co;
        }
    }
    else {
        ret.max = l.max;
        ret.maxco = l.maxco + r.maxco;
        if (l.max2 >= r.max2) {
            ret.max2 = l.max2;
            ret.max2co = l.max2co;
            if (l.max2 == r.max2) ret.max2co += r.max2co;
        }
        else {
            ret.max2 = r.max2;
            ret.max2co = r.max2co;
        }
    }
    ret.sum = l.sum + r.sum;
}

void init(int t1, int t2, int idx) {
    lazy[idx] = 0;
    if (t1 == t2) {
        seg[idx].max = seg[idx].sum = h[t1];
        seg[idx].max2 = -1;
        seg[idx].maxco = 1;
        seg[idx].max2co = 0;
        return;
    }
    int mid = (t1 + t2) >> 1;
    init(t1, mid, idx << 1);
    init(mid + 1, t2, idx << 1 | 1);
    merge(seg[idx], seg[idx << 1], seg[idx << 1 | 1]);
}

void dolazy(bool push, int idx) {
    if (push) {
        if (seg[idx << 1].max - lazy[idx << 1] == seg[idx].max) lazy[idx << 1] += lazy[idx];
        if (seg[idx << 1 | 1].max - lazy[idx << 1 | 1] == seg[idx].max) lazy[idx << 1 | 1] += lazy[idx];
    }
    seg[idx].max -= lazy[idx];
    seg[idx].sum -= (ll)lazy[idx] * seg[idx].maxco;
    lazy[idx] = 0;
}

void mupdate(int t1, int t2, int q, int val, int idx) {
    dolazy(t1 < t2, idx);
    if (q < t1 || t2 < q) return;
    if (t1 == t2) {
        seg[idx].max = seg[idx].sum = val;
        seg[idx].max2 = -1;
        seg[idx].maxco = 1;
        seg[idx].max2co = 0;
        return;
    }
    int mid = (t1 + t2) >> 1;
    mupdate(t1, mid, q, val, idx << 1);
    mupdate(mid + 1, t2, q, val, idx << 1 | 1);
    merge(seg[idx], seg[idx << 1], seg[idx << 1 | 1]);
}

Node query(int t1, int t2, int q1, int q2, int idx) {
    dolazy(t1 < t2, idx);
    if (q1 <= t1 && t2 <= q2) return seg[idx];
    int mid = (t1 + t2) >> 1;
    if (q2 <= mid) return query(t1, mid, q1, q2, idx << 1);
    if (mid + 1 <= q1) return query(mid + 1, t2, q1, q2, idx << 1 | 1);
    Node ret, l = query(t1, mid, q1, q2, idx << 1), r = query(mid + 1, t2, q1, q2, idx << 1 | 1);
    merge(ret, l, r);
    return ret;
}

void cupdate(int t1, int t2, int q1, int q2, int& lco, int val, int idx) {
    dolazy(t1 < t2, idx);
    if (q2 < t1 || t2 < q1 || !lco || seg[idx].max <= val) return;
    if (q1 <= t1 && t2 <= q2 && seg[idx].max2 < val && seg[idx].maxco <= lco) {
        lco -= seg[idx].maxco;
        lazy[idx] = seg[idx].max - val;
        dolazy(t1 < t2, idx);
        return;
    }
    if (t1 == t2) {
        lco--;
        seg[idx].max = seg[idx].sum = val;
        seg[idx].max2 = -1;
        seg[idx].maxco = 1;
        seg[idx].max2co = 0;
        return;
    }
    int mid = (t1 + t2) >> 1;
    cupdate(t1, mid, q1, q2, lco, val, idx << 1);
    cupdate(mid + 1, t2, q1, q2, lco, val, idx << 1 | 1);
    merge(seg[idx], seg[idx << 1], seg[idx << 1 | 1]);
}

void initialise(int Nin, int Q, int hin[]) {
    N = Nin;
    for (int i = 0; i < N; i++) h[i] = hin[i];
    init(0, N - 1, 1);
}
void cut(int l, int r, int k) {
    l--;
    r--;
    while (k) {
        Node qval = query(0, N - 1, l, r, 1);
        if (!qval.max) break;
        if (qval.maxco > k) {
            cupdate(0, N - 1, l, r, k, qval.max - 1, 1);
            assert(!k);
            break;
        }
        else {
            int cutlv = min(k / qval.maxco, qval.max - max(qval.max2, 0));
            if (!cutlv) break;
            k -= cutlv * qval.maxco;
            cupdate(0, N - 1, l, r, qval.maxco, qval.max - cutlv, 1);
            assert(!qval.maxco);
        }
    }
}
void magic(int i, int x) {
    mupdate(0, N - 1, --i, x, 1);
}
ll inspect(int l, int r) {
    inspect(l, r);
    return query(0, N - 1, --l, --r, 1).sum;
}





/*
int hinin[6] = {1, 2, 3, 1, 2, 3};

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    initialise(6, 10, hinin);

    cut(1, 6, 3);
    cout << inspect(1, 6) << '\n';
    cut(1, 3, 3);
    cout << inspect(1, 6) << '\n';
    cut(1, 3, 1000);
    cout << inspect(1, 6) << '\n';
    //for (int i = 0; i < 6; i++) cout << query(0, 5, i, i, 1).sum << ' ';
    //cout << '\n';
    magic(1, 1000);
    cout << inspect(1, 6) << '\n';
    cut(1, 3, 999);
    cout << inspect(1, 5) << '\n';
}
*/
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...