Untitled

 avatar
unknown
plain_text
a year ago
4.7 kB
10
Indexable
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;

#define fi first
#define se second
#define pp push_back
#define all(x) (x).begin(), (x).end()
#define Ones(n) __builtin_popcount(n)
#define endl '\n'
#define mem(arrr, xx) memset(arrr,xx,sizeof arrr)
//#define int long long
#define debug(x) cout << (#x) << " = " << x << endl

void Gamal() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
#ifdef Clion
    freopen("input.txt", "r", stdin), freopen("output.txt", "w", stdout);
#endif
}

int dx[] = {+0, +0, -1, +1, +1, +1, -1, -1};
int dy[] = {-1, +1, +0, +0, +1, -1, +1, -1};

const double EPS = 1e-9;
const ll OO = 0X3F3F3F3F3F3F3F3F;
const int N = 2e5 + 5, INF = INT_MAX, MOD = 1e9 + 7, LOG = 20;

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

// Node struct is unchanged
struct Node {
    long long sum, lazy;
    Node *l, *r;

    Node(long long s = 0, long long z = 0, Node *L = nullptr, Node *R = nullptr)
            : sum(s), lazy(z), l(L), r(R) {}
};

struct PST {
    int n;
    vector<Node *> roots;

    PST(int _n) {
        n = _n;
        roots = {new Node()}; // Version 0 is an empty tree
    }

    // Public update interface (unchanged)
    int update(int root_id, int l, int r, long long val) {
        roots.push_back(upd(roots[root_id], 0, n - 1, l, r, val));
        return (int) roots.size() - 1;
    }

    // Public query interface (unchanged)
    long long query(int root_id, int l, int r) {
        return qry(roots[root_id], 0, n - 1, l, r);
    }

private:
    // Helper to clone a node (unchanged)
    Node *clone(Node *p) {
        if (!p) return new Node();
        return new Node(p->sum, p->lazy, p->l, p->r);
    }

    // Push function (unchanged and correct for updates)
    void push(Node *p, int s, int e) {
        if (!p || !p->lazy || s == e) return;
        int m = (s + e) >> 1;

        // Persistently update children by cloning them before modification
        p->l = clone(p->l);
        p->r = clone(p->r);

        p->l->sum += p->lazy * (m - s + 1);
        p->l->lazy += p->lazy;

        p->r->sum += p->lazy * (e - m);
        p->r->lazy += p->lazy;

        p->lazy = 0;
    }

    // Update function (unchanged and correct)
    Node *upd(Node *p, int s, int e, int l, int r, long long v) {
        Node *res = clone(p);
        if (r < s || e < l) return res;

        if (l <= s && e <= r) {
            res->sum += v * (e - s + 1);
            res->lazy += v;
            return res;
        }

        push(res, s, e);
        int m = (s + e) >> 1;
        res->l = upd(res->l, s, m, l, r, v);
        res->r = upd(res->r, m + 1, e, l, r, v);

        res->sum = (res->l ? res->l->sum : 0) + (res->r ? res->r->sum : 0);
        return res;
    }

    // Query function (CORRECTED)
    long long qry(Node *p, int s, int e, int l, int r) {
        if (!p || r < s || e < l) return 0;

        if (l <= s && e <= r) {
            return p->sum;
        }

        int m = (s + e) >> 1;

        long long intersection_l = max(s, l);
        long long intersection_r = min(e, r);

        long long lazy_contribution = 0;
        if (intersection_l <= intersection_r) {
            lazy_contribution = p->lazy * (intersection_r - intersection_l + 1);
        }

        return lazy_contribution + qry(p->l, s, m, l, r) + qry(p->r, m + 1, e, l, r);
    }
};


void solve() {
    int n, m, q;
    cin >> n >> m >> q;
    vector<PST> seg(m, PST(1e5 + 2));
    vector<ll> sum(m);
    for (int i = 0; i < n; ++i) {
        int b, l, r;
        cin >> b >> l >> r;
        b--, l--, r--;
        seg[b].update(seg[b].roots.size() - 1, l, r, +1);
        sum[b] += r - l + 1;
    }
    while (q--) {
        int p;
        cin >> p;
        if (p == 3) {
            int b, x;
            cin >> b >> x;
            b--, x--;
            ll tot = seg[b].query(seg[b].roots.size() - 1, 0, 1e5);
            ll occ = seg[b].query(seg[b].roots.size() - 1, x, x);
            cout << fixed << setprecision(8) << 1.0 * occ / tot << endl;
        } else {
            int b, l, r;
            cin >> b >> l >> r;
            b--, l--, r--;
            seg[b].update(seg[b].roots.size() - 1, l, r, (p == 1 ? 1 : -1));
            sum[b] += (r - l + 1) * (p == 1 ? 1 : -1);
        }
    }

}


signed main() {
    Gamal();
    int t = 1;
//    cin >> t;
    while (t--) {
        solve();
    }
}
Editor is loading...
Leave a Comment