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);
		}
	}
}

  

猜你喜欢

转载自www.cnblogs.com/pkgunboat/p/10700242.html
今日推荐