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;
}
/*
*/