BZOJ1577: [Usaco2009 Feb]庙会捷运Fair Shuttle

看上去并不可 dp,实际也不可 dp

考虑线段树

当前还能上车的数量可以用线段树维护

考虑把区间按右端点排序,这样就可以贪心了

并不会证明,感觉挺显然?

大概就是你让早下车的上来了而不让晚下车的来
这样可以让后边尽量上更多的

大概这样就行了

需要注意的是区间操作中都是 [l, r - 1]

因为你可以让牛都先下车再上,
这样相当于是和当前没有这些牛是一样的

表示一开始并没想到啊...


 代码:

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cstdio>
#define lson (x << 1)
#define rson ((x << 1) | 1)
using namespace std;

const int MAXN = 20005, MAXK = 50005;

struct Line{
	int l, r, siz;
	bool operator < (const Line& b) const {
		return ((r == b.r) ? (l > b.l) : (r < b.r));
	}
}que[MAXK];
struct Node{
	int minn, lzy;
}t[MAXN << 2];
int n, k, c, res;

inline int rd() {
	register int x = 0;
	register char c = getchar();
	while(!isdigit(c)) c = getchar();
	while(isdigit(c)) {
		x = x * 10 + (c ^ 48);
		c = getchar();
	}
	return x;
}
inline void pushup(int x) {
	t[x].minn = min(t[lson].minn, t[rson].minn);
	return;
}
inline void pushdown(int x) {
	register int lzy = t[x].lzy;
	t[lson].lzy += lzy;
	t[rson].lzy += lzy;
	t[lson].minn += lzy;
	t[rson].minn += lzy;
	t[x].lzy = 0;
	return;
}
void update(int L, int R, int l, int r, int x, int val) {
	if(L <= l && r <= R) {
		t[x].lzy += val;
		t[x].minn += val;
		return;
	}
	int mid = ((l + r) >> 1);
	if(t[x].lzy) pushdown(x);
	if(L <= mid) update(L, R, l, mid, lson, val);
	if(mid < R) update(L, R, mid + 1, r, rson, val);
	pushup(x);
	return;
}
int query(int L, int R, int l, int r, int x) {
	if(L <= l && r <= R) return t[x].minn;
	int mid = ((l + r) >> 1), ans = 0x3f3f3f3f;
	if(t[x].lzy) pushdown(x);
	if(L <= mid) ans = query(L, R, l, mid, lson);
	if(mid < R) ans = min(ans, query(L, R, mid + 1, r, rson));
	return ans;
}

int main() {
	k = rd(); n = rd(); c = rd();
	update(1, n, 1, n, 1, c);
	for(int i = 1; i <= k; ++i) {
		que[i].l = rd();
		que[i].r = rd();
		que[i].siz = rd();
	}
	sort(que + 1, que + k + 1);
	register int tmp = 0;
	for(int i = 1; i <= k; ++i) {
		tmp = min(que[i].siz, query(que[i].l, que[i].r - 1, 1, n, 1));
		if(!tmp) continue;
		res += tmp;
		update(que[i].l, que[i].r - 1, 1, n, 1, -tmp);
	}
	printf("%d\n", res);
	return 0;
}

猜你喜欢

转载自www.cnblogs.com/xcysblog/p/9762495.html