Codeforces 1109C 线段树
题意及思路:https://www.cnblogs.com/TinyWong/p/10400682.html
代码:
#include <bits/stdc++.h> #define ls(x) (x << 1) #define rs(x) ((x << 1) | 1) #define LL long long #define db long double #define INF 1e15; using namespace std; const int maxn = 200010; LL t[maxn * 2]; LL add[maxn * 2]; map<LL, int> mp; int m; db ans, v; struct OP{ LL id, x, y, z; }; OP op[maxn]; set<int> s; set<int>::iterator it, it1, it2; struct SegmentTree { LL sum, lsum, Set; int l, r; bool flag; }; SegmentTree tr[maxn * 4]; void pushup(int o) { tr[o].sum = tr[ls(o)].sum + tr[rs(o)].sum; tr[o].lsum = min(tr[ls(o)].lsum, tr[ls(o)].sum + tr[rs(o)].lsum); } void maintain(int o, LL val) { tr[o].sum = val * (t[tr[o].r + 1] - t[tr[o].l]); tr[o].lsum = min(0ll, tr[o].sum); tr[o].Set = val; tr[o].flag = 1; } void pushdown(int o) { if(tr[o].flag) { maintain(ls(o), tr[o].Set); maintain(rs(o), tr[o].Set); tr[o].flag = 0; } } void build(int o, int l, int r) { tr[o].l = l, tr[o].r = r; if(l == r) { tr[o].flag = 0; tr[o].sum = 0; tr[o].lsum = 0; return; } int mid = (l + r) >> 1; build(ls(o), l, mid); build(rs(o), mid + 1, r); pushup(o); } void update(int o, int l, int r, int ql, int qr, LL val) { if(l >= ql && r <= qr) { maintain(o, val); return; } pushdown(o); int mid = (l + r) >> 1; if(ql <= mid) update(ls(o), l, mid, ql, qr, val); if(qr > mid) update(rs(o), mid + 1, r, ql, qr, val); pushup(o); } void query(int o, int l, int r, int ql, int qr) { if(ql > qr) return; if(l == r) { if(tr[o].lsum + v > 0) { v += tr[o].sum; return; } db tmp = v / (-((db)tr[o].Set)); if(tmp <= 0 || (tmp + t[l] > t[qr + 1])) { v += tr[o].sum; return; } ans = tmp + (db)t[l]; return; } pushdown(o); int mid = (l + r) >> 1; if(l >= ql && r <= qr) { if(tr[o].lsum + v > 0) { v += tr[o].sum; return; } if(v + tr[ls(o)].lsum <= 0) { query(ls(o), l, mid, ql, qr); if(ans != -1) return; } v += tr[ls(o)].sum; if(v + tr[rs(o)].lsum <= 0) { query(rs(o), mid + 1, r, ql, qr); if(ans != -1) return; } v += tr[rs(o)].sum; return; } if(ql <= mid) query(ls(o), l, mid, ql, qr); if(ans != -1) return; if(qr > mid) query(rs(o), mid + 1, r, ql, qr); } int main() { int n; scanf("%d", &n); int cnt = 0; for (int i = 1; i <= n; i++) { scanf("%lld", &op[i].id); if(op[i].id == 1) { scanf("%lld%lld", &op[i].x, &op[i].y); t[++cnt] = op[i].x; } else if(op[i].id == 2) { scanf("%lld", &op[i].x); t[++cnt] = op[i].x; } else { scanf("%lld%lld%lld", &op[i].x, &op[i].y, &op[i].z); t[++cnt] = op[i].x; t[++cnt] = op[i].y; } } sort(t + 1, t + 1 + cnt); m = unique(t + 1, t + 1 + cnt) - (t + 1); for (int i = 1; i <= m; i++) { mp[t[i]] = i; } t[m + 1] = 1e9 + 1; t[0] = 0; build(1, 1, m); s.insert(m + 1); s.insert(0); for (int i = 1; i <= n; i++) { if(op[i].id == 1) { s.insert(mp[op[i].x]); it = s.lower_bound(mp[op[i].x]); it++; update(1, 1, m, mp[op[i].x], (*it) - 1, op[i].y); add[mp[op[i].x]] = op[i].y; } else if(op[i].id == 2) { it = s.lower_bound(mp[op[i].x]); it1 = it, it2 = it; it1--, it2++; int num; if((*it1) == 0) { num = 1; } else { num = (*it1); } update(1, 1, m, num, (*it2) - 1, add[num]); add[*it] = 0; s.erase(it); } else { ans = -1; v = op[i].z; if(v == 0) { printf("%d\n", op[i].x); continue; } it = s.lower_bound(mp[op[i].x]); query(1, 1, m, *it, mp[op[i].y] - 1); printf("%.10Lf\n", ans); } } }