[CC-MCHEF]MasterChef

[CC-MCHEF]MasterChef

题目大意:

\(n(n\le10^5)\)片花,第\(i\)片花的美观度为\(b_i(|b_i|\le10^9)\)。总体美观度为各片花的美观度之和。

由于有些花太丑了,要把它们除掉。有\(m\)位工人,第\(i\)位工人只会除编号在\(l_i\)\(r_i\)之间的花,且每除一片花,收费\(c_i\)元。总共有\(k\)元的资金预算,问工人除完花后,总体美观度最大是多少。

思路:

首先计算不除掉的答案。

线段树求区间最小值以后可以得到移除每个花的代价,然后背包就行了。

时间复杂度\(\mathcal O(n\log n+nk)\)

源代码:

#include<cstdio>
#include<cctype>
#include<climits>
#include<algorithm>
inline int getint() {
	register char ch;
	register bool neg=false;
	while(!isdigit(ch=getchar())) neg|=ch=='-';
	register int x=ch^'0';
	while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
	return neg?-x:x;
}
typedef long long int64;
const int N=1e5+1,K=501;
int b[N];
int64 f[K];
class SegmentTree {
	#define _left <<1
	#define _right <<1|1
	#define mid ((b+e)>>1)
	private:
		int val[N<<2];
	public:
		void build(const int &p,const int &b,const int &e) {
			val[p]=INT_MAX;
			if(b==e) return;
			build(p _left,b,mid);
			build(p _right,mid+1,e);
		}
		void modify(const int &p,const int &b,const int &e,const int &l,const int &r,const int &x) {
			if(b==l&&e==r) {
				val[p]=std::min(val[p],x);
				return;
			}
			if(l<=mid) modify(p _left,b,mid,l,std::min(mid,r),x);
			if(r>mid) modify(p _right,mid+1,e,std::max(mid+1,l),r,x);
		}
		int query(const int &p,const int &b,const int &e,const int &x) const {
			int ret=val[p];
			if(b==e) return ret;
			if(x<=mid) ret=std::min(ret,query(p _left,b,mid,x));
			if(x>mid) ret=std::min(ret,query(p _right,mid+1,e,x));
			return ret;
		}
	#undef _left
	#undef _right
	#undef mid
};
SegmentTree t;
int main() {
	for(register int T=getint();T;T--) {
		const int n=getint(),k=getint(),m=getint();
		std::fill(&f[0],&f[k]+1,0);
		int64 ans=0;
		for(register int i=1;i<=n;i++) {
			b[i]=getint();
			ans+=b[i];
		}
		t.build(1,1,n);
		for(register int i=0;i<m;i++) {
			const int l=getint(),r=getint(),c=getint();
			t.modify(1,1,n,l,r,c);
		}
		for(register int i=1;i<=n;i++) {
			if(b[i]>=0) continue;
			const int c=t.query(1,1,n,i);
			for(register int j=k;j>=c;j--) {
				f[j]=std::max(f[j],f[j-c]-b[i]);
			}
		}
		printf("%lld\n",ans+f[k]);
	}
	return 0;
}
posted @ 2018-08-20 18:55  skylee03  阅读(239)  评论(0编辑  收藏  举报