CF1271D Portals

题目

CF1271D Portals

分析

直接讲 \(n\log n\) 做法,没看 \(dp\)\(n^2\)

首先我们肯定可以想到这样的一个策略:先尽可能的多攻打,最后再回来考虑到底可以安插多少个获取得分。

而阻止我们安插的其实就是在当前点之后攻占所有城市需要的“已有兵力-需要兵力”的最小值,我们最多就可以插入这么多个去获取得分。

于是就想到对得分从大到小排序,然后贪心选,每次更新在这个城市之后的“已有兵力-需要兵力”的最小值,可以线段树维护区间加和区间取最小值。

然后就结束了。

代码

#include<bits/stdc++.h>
using namespace std;
#ifdef ONLINE_JUDGE
	#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
	char buf[1<<21],*p1=buf,*p2=buf;
#endif
template<typename T>
inline void read(T &x){
	x=0;bool f=false;char ch=getchar();
	while(!isdigit(ch)){f|=ch=='-';ch=getchar();}
	while(isdigit(ch)){x=x*10+(ch^48);ch=getchar();}
	x=f?-x:x;
	return ;
}
template<typename T>
inline void write(T x){
	if(x<0) x=-x,putchar('-');
	if(x>9) write(x/10);
	putchar(x%10^48);
	return ;
}
#define ll long long
#define ull unsigned long long
#define ld long double
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define pc putchar
#define PII pair<int,int>
#define rep(i,x,y) for(register int i=(x);i<=(y);i++)
#define dep(i,y,x) for(register int i=(y);i>=(x);i--)
const int MOD=1e9+7;
inline int inc(int x,int y){x+=y;return x>=MOD?x-MOD:x;}
inline int dec(int x,int y){x-=y;return x<0?x+MOD:x;}
inline void incc(int &x,int y){x+=y;if(x>=MOD) x-=MOD;}
inline void decc(int &x,int y){x-=y;if(x<0) x+=MOD;}
inline void chkmin(int &x,int y){if(y<x) x=y;}
inline void chkmax(int &x,int y){if(y>x) x=y;}
const int N=1e5+5,M=2e5+5,INF=1e9+7;
int n,m,k,a[N],b[N],c[N],num[N],dp[N],las[N];
PII d[N];
int Min[N<<2],tag[N<<2];
void PushDown(int x){
	Min[x<<1]+=tag[x],Min[x<<1|1]+=tag[x];
	tag[x<<1]+=tag[x],tag[x<<1|1]+=tag[x];
	tag[x]=0;
	return ;
}
inline void Pushup(int x){
	Min[x]=min(Min[x<<1],Min[x<<1|1]);
	return ;
}
void Modify(int x,int l,int r,int ql,int qr,int v){
	if(ql<=l&&r<=qr) return Min[x]--,tag[x]--,void();
	if(tag[x]!=0) PushDown(x);
	int mid=l+r>>1;
	if(ql<=mid) Modify(x<<1,l,mid,ql,qr,v);
	if(qr>mid) Modify(x<<1|1,mid+1,r,ql,qr,v);
	Pushup(x);
	return ;
}
int Query(int x,int l,int r,int ql,int qr){
	if(ql<=l&&r<=qr) return Min[x];
	PushDown(x);
	int mid=l+r>>1,res=INF;
	if(ql<=mid) res=Query(x<<1,l,mid,ql,qr);
	if(qr>mid) chkmin(res,Query(x<<1|1,mid+1,r,ql,qr));
	return res;
}
void Build(int x,int l,int r){
	if(l==r) return Min[x]=las[l],void();
	int mid=l+r>>1;
	Build(x<<1,l,mid),Build(x<<1|1,mid+1,r);
	Pushup(x);
	return ;
}
int Ans;
signed main(){
//	freopen(".in","r",stdin);
//	freopen(".out","w",stdout);
//	ios::sync_with_stdio(false);
	double ST=clock();
	read(n),read(m),read(k);
	int u,v;
	rep(i,1,n) read(a[i]),read(b[i]),read(c[i]),num[i]=i;
	rep(i,1,m) read(u),read(v),chkmax(num[v],u);
	rep(i,1,n) d[i]=mp(c[i],num[i]);
	sort(d+1,d+n+1);
	int tmp=k;
	rep(i,1,n){
		if(tmp<a[i]){
			puts("-1");
			return 0;
		}
		las[i-1]=tmp-a[i];
		tmp+=b[i];
	}
	las[n]=tmp;
	Build(1,1,n);
	dep(i,n,1){
		int val=d[i].fi,pos=d[i].se;
		if(Query(1,1,n,pos,n)<=0) continue;
		Modify(1,1,n,pos,n,-1);Ans+=val;
	}
	write(Ans);
#ifndef ONLINE_JUDGE
	cerr<<"\nTime:"<<(clock()-ST)/CLOCKS_PER_SEC<<"s\n";
#endif
	return 0;
}
/*

*/



posted @ 2021-10-26 20:40  __Anchor  阅读(31)  评论(0编辑  收藏  举报