求调 0pts
查看原帖
求调 0pts
729386
_Fancy_楼主2024/10/21 21:46
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6 + 5;
int cases, T, n, tmpn, m, k, d, ans, tmp[N], tot;
struct node {
	int l, r, v;
} a[N];
bool cmp(node a, node b) {
	return a.r < b.r;
}
int find(int x) {
	return lower_bound(tmp + 1, tmp + tot + 1, x) - tmp;
}
namespace segment {
	struct tree {
		int l, r, maxx, tag;
	} tr[N * 4];
	void pushup(int u) {
		tr[u].maxx = max(tr[u << 1].maxx, tr[u << 1 | 1].maxx);
	}
	void pushdown(tree &u, tree &l, tree &r) {
		if(u.tag != 0) {
			l.tag += u.tag, l.maxx += u.tag;
			r.tag += u.tag, r.maxx += u.tag;
			u.tag = 0;
		}
	}
	void pushdown(int u) {
		pushdown(tr[u], tr[u << 1], tr[u << 1 | 1]);
	}
	void build(int u, int l, int r) {
		tr[u] = {l, r, 0, 0};
		if(l == r) return;
		int mid = l + r >> 1;
		build(u << 1, l, mid);
		build(u << 1 | 1, mid + 1, r);
		pushup(u);
	}
	void modify(int u, int l, int r, int k) {
		if(l <= tr[u].l && tr[u].r <= r) {
			tr[u].maxx += k, tr[u].tag += k;
			return;
		}
		pushdown(u);
		int mid = tr[u].l + tr[u].r >> 1;
		if(l <= mid) modify(u << 1, l, r, k);
		if(r > mid) modify(u << 1 | 1, l, r, k);
		pushup(u);
	}
	int query(int u, int l, int r) {
		if(l <= tr[u].l && tr[u].r <= r) return tr[u].maxx;
		pushdown(u);
		int mid = tr[u].l + tr[u].r >> 1, ans = -1e18;
		if(l <= mid) ans = max(ans, query(u << 1, l, r));
		if(r > mid) ans = max(ans, query(u << 1 | 1, l, r));
		return ans;
	}
}
using namespace segment;
signed main() {
	scanf("%lld%lld", &cases, &T);
	while(T--) {
		scanf("%lld%lld%lld%lld", &n, &m, &k, &d), tot = 0;
		for(int i = 1, x1, x2, x3; i <= m; i++) {
			scanf("%lld%lld%lld", &x1, &x2, &x3);
			a[i] = {x1 - x2 + 1, x1, x3};
			tmp[++tot] = a[i].l, tmp[++tot] = a[i].r;
		}
		sort(tmp + 1, tmp + tot + 1);
		tmpn = unique(tmp + 1, tmp + tot + 1) - tmp - 1;
		for(int i = 1; i <= m; i++) {
			a[i].l = find(a[i].l), a[i].r = find(a[i].r);
		}
		sort(a + 1, a + m + 1, cmp);
		build(1, 0, tmpn);
		int now = 1, ans = 0;
		for(int i = 1; i <= tmpn; i++) {
			modify(1, 0, i - 1, -d * (tmp[i] - tmp[i - 1]));
			while(now <= m && a[now].r == i) modify(1, 0, a[now].l, a[now].v), now++;
			ans = max(ans, query(1, find(tmp[i] - k), i - 1));
			if(i + 1 < tmpn) modify(1, i + 1, i + 1, ans);
		}
		printf("%lld\n", ans);
	}
	return 0;
}
2024/10/21 21:46
加载中...