Submission #622359

#TimeUsernameProblemLanguageResultExecution timeMemory
622359maeolaWeirdtree (RMI21_weirdtree)C++17
52 / 100
2047 ms56012 KiB
#include "weirdtree.h"
#include <bits/stdc++.h>
using namespace std;

using ll = long long;

constexpr int L = 0x3f3f3f3f;

struct P
{
    int mx, freq, mx2;
    ll sum;
};

P operator + (const P &a, const P& b)
{
    P p;
    if (a.mx == b.mx)
    {
        p.mx = a.mx;
        p.mx2 = max(a.mx2, b.mx2);
        p.freq = a.freq + b.freq;
    }else if (a.mx > b.mx)
    {
        p.mx = a.mx;
        p.mx2 = max(a.mx2, b.mx);
        p.freq = a.freq;
    }else{
        p.mx = b.mx;
        p.mx2 = max(a.mx, b.mx2);
        p.freq = b.freq;
    }
    p.sum = a.sum + b.sum;
    return p;
}

struct Node
{
    int lc, rc;
    P p;
    int lazy;
};

Node nodes[5000000];
int new_node()
{
    static int upto = 0;
    auto &node = nodes[++upto];
    node.lazy = L;
    return upto;
}

void clean(int i)
{
    auto &node = nodes[i];
    if (not node.lc)
    {
        node.lc = new_node();
        node.rc = new_node();
    }
    if (node.lazy >= node.p.mx)
    {
        node.lazy = L;
        return;
    }
    node.p.sum -= (ll) node.p.freq * (node.p.mx - node.lazy);
    node.p.mx = node.lazy;
    nodes[node.lc].lazy = min(nodes[node.lc].lazy, node.lazy);
    nodes[node.rc].lazy = min(nodes[node.rc].lazy, node.lazy);
    node.lazy = L;
}

void upd(int i, int l, int r, int p, int x)
{
    auto &node = nodes[i];
    clean(i);
    if (p < l or p > r)
        return;
    if (l == r)
    {
        node.p.mx = x, node.p.freq = 1, node.p.mx2 = 0, node.p.sum = x;
        return;
    }
    int m = l + (r - l) / 2;
    upd(node.lc, l, m, p, x);
    upd(node.rc, m + 1, r, p, x);
    node.p = nodes[node.lc].p + nodes[node.rc].p;
}

void cap(int i, int l, int r, int ql, int qr, int x)
{
    auto &node = nodes[i];
    clean(i);
    if (qr < l or ql > r)
        return;
    if ((ql <= l and qr >= r and x > node.p.mx2) or l == r)
    {
        node.lazy = x;
        clean(i);
        return;
    } 
    int m = l + (r - l) / 2;
    cap(node.lc, l, m, ql, qr, x);
    cap(node.rc, m + 1, r, ql, qr, x);
    node.p = nodes[node.lc].p + nodes[node.rc].p;
}

P query(int i, int l, int r, int ql, int qr)
{
    auto &node = nodes[i];
    clean(i);
    if (qr < l or ql > r)
        return {0, 0, 0, 0};
    if (ql <= l and qr >= r)
        return node.p;
    int m = l + (r - l) / 2;
    return query(node.lc, l, m, ql, qr) + query(node.rc, m + 1, r, ql, qr);
}

int N;
int root = new_node();

void initialise(int N, int Q, int h[])
{
    ::N = N;
    for (int i = 1; i <= N; i++)
    {
        upd(root, 1, N, i, h[i]);
    }
}

void cut(int l, int r, int k)
{
    if (k <= 0) return;
    auto p = query(root, 1, N, l, r);
    int g = min<ll>(k, (ll) p.freq * (p.mx - p.mx2));
    if (p.mx == 0) return;
    int pi = g % p.freq;
    int pc = g / p.freq;
    if (pi == 0)
    {
        cap(root, 1, N, l, r, p.mx - pc);
    }else{
        int a = l, b = r + 1;
        while (b - a > 1)
        {
            int m = a + (b - a) / 2;
            auto f = query(root, 1, N, l, m - 1);
            if ((f.mx == p.mx ? f.freq : 0) >= pi)
            {
                b = m;
            }else{
                a = m;
            }
        }
#ifdef DEBUG
        auto d = query(root, 1, N, l, a);
        cout << "D: " << l << ' ' << a << ' ' << r << ' ' << d.freq << ' ' << d.mx << endl;
#endif
        cap(root, 1, N, l, a, p.mx - pc - 1);
        cap(root, 1, N, a + 1, r, p.mx - pc);
    }
    cut(l, r, k - g);
}

void magic(int i, int x)
{
    upd(root, 1, N, i, x);
}

ll inspect(int l, int r)
{
    return query(root, 1, N, l, r).sum;
}
#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...