动态开点线段树板子MLEonTest5求条,马风还行
查看原帖
动态开点线段树板子MLEonTest5求条,马风还行
386547
Infter楼主2024/10/19 13:11

rt

#include <bits/stdc++.h>
using namespace std;

#define int long long
#define endl '\n'
#define debug(x) cerr << #x << " = " << x << endl
#define rep(i, a, b) for (int i = (a); i <= (b); i++)
#define per(i, a, b) for (int i = (a); i >= (b); i--)
#define gn(u, v) for (int v : G.G[u])
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define pii pair<int, int>
#define vi vector<int>
#define vpii vector<pii>
#define vvi vector<vi>
#define no cout << "NO" << endl
#define yes cout << "YES" << endl
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define tomin(x, y) ((x) = min((x), (y)))
#define tomax(x, y) ((x) = max((x), (y)))
#define ck(mask, i) (((mask) >> (i)) & 1)
#define pq priority_queue

pii operator + (const pii &x, const pii &y) {
    return mp(x.fi + y.fi, x.se + y.se);
}

constexpr int MAXN = 1e5 + 5;
constexpr double eps = 1e-5;
int n, q;
int h[MAXN];

struct AutoPointSegTree {
    struct Node {
        int l, r, ls, rs, cnt, sum;
        Node() {}
        Node(int _l, int _r, int _ls, int _rs, int _cnt, int _sum) {
            l = _l;
            r = _r;
            ls = _ls;
            rs = _rs;
            cnt = _cnt;
            sum = _sum;
        }
    };
    vector<Node> tr;
    AutoPointSegTree() {
        tr.push_back(Node(0, 0, 0, 0, 0, 0));
        tr.push_back(Node(0, 1e15, 0, 0, 0, 0));
    }
    
    void mkl(int u) {
        int md = tr[u].l + tr[u].r >> 1;
        if (!tr[u].ls) {
            tr[u].ls = sz(tr);
            tr.pb(Node(tr[u].l, md, 0, 0, 0, 0));
        }
    }
    void mkr(int u) {
        int md = tr[u].l + tr[u].r >> 1;
        if (!tr[u].rs) {
            tr[u].rs = sz(tr);
            tr.pb(Node(md + 1, tr[u].r, 0, 0, 0, 0));
        }
    }

    void pull(int k) {
        tr[k].sum = tr[tr[k].ls].sum + tr[tr[k].rs].sum;
        tr[k].cnt = tr[tr[k].ls].cnt + tr[tr[k].rs].cnt;
    }

    void update(int k, int p, int v, int sg) {
        if (tr[k].l == tr[k].r) {
            tr[k].cnt += sg;
            tr[k].sum += sg * v;
            return;
        }
        mkl(k);
        int md = tr[k].l + tr[k].r >> 1;
        if (p <= md) {
            mkl(k);
            update(tr[k].ls, p, v, sg);
        } else  {
            mkr(k);
            update(tr[k].rs, p, v, sg);
        }
        pull(k);
    }

    pii query(int k, int l, int r) {
        if (tr[k].l >= l && tr[k].r <= r)
            return mp(tr[k].cnt, tr[k].sum);
        int md = tr[k].l + tr[k].r >> 1;
        if (r <= md) {
            mkl(k);
            return query(tr[k].ls, l, r);
        } else if (l > md) {
            mkr(k);
            return query(tr[k].rs, l, r);
        } else {
            mkl(k);
            mkr(k);
            return query(tr[k].ls, l, md) + query(tr[k].rs, md + 1, r);
        }
    }
};

int id[MAXN];

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    cin >> n >> q;
    rep(i, 1, n)
        cin >> h[i];
    rep(i, 1, n) id[i] = i;
    sort(id + 1, id + n + 1, [&](int x, int y) {
        return h[x] < h[y];
    });
    AutoPointSegTree seg;
    rep(i, 1, n) {
        seg.update(1, h[i], h[i], 1);
    }
    rep(i, 1, q) {
        int op, x, y;
        cin >> op >> x;
        if (op == 1) {
            cin >> y;
            seg.update(1, h[x], h[x], -1);
            h[x] = y;
            seg.update(1, h[x], h[x], 1);
        } else if (op == 2) {
            double t = 0;
            for (double j = (1ll << 55); j >= eps; j /= 2) {
                auto [a, b] = seg.query(1, 0, t + j);
                if (a * (t + j) - b - eps <= x) {
                    t += j;
                }
            }
            cout << t << endl;
        }
    }

    return 0;
}
2024/10/19 13:11
加载中...