题意:一架航班要从
一道显而易见的贪心(好像有纯贪心的做法但是还是用的线段树)。
我们设一个数组
区间求最小值和更新,线段树来一发。
然后剩下的就是处理各种牛的要求了,由于贪心策略,我们把要求
注意点:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define INF 1e9
using namespace std;
const int maxn=1e4+101,maxk=5e4+101;
int n,k,c,ans;
int minn[maxn<<4],add[maxn<<4];
struct cow
{
int s;
int t;
int m;
}a[maxk];
int cmp(cow a,cow b)
{
if(a.t!=b.t)
return a.t<b.t;
return a.s>b.s;
}
void pushup(int rt)
{
minn[rt]=min(minn[rt<<1],minn[rt<<1|1]);
}
void pushdown(int rt)
{
if(add[rt]!=0)
{
minn[rt<<1]+=add[rt];
minn[rt<<1|1]+=add[rt];
add[rt<<1]+=add[rt];
add[rt<<1|1]+=add[rt];
add[rt]=0;
return ;
}
}
void build(int l,int r,int rt)
{
add[rt]=0;
minn[rt]=c;
if(l==r)
return ;
int mid=(l+r)>>1;
build(lson);
build(rson);
pushup(rt);
}
void update(int L,int R,int val,int l,int r,int rt)
{
if(L<=l&&r<=R)
{
minn[rt]+=val;
add[rt]+=val;
return ;
}
int mid=(l+r)>>1;
pushdown(rt);
if(L<=mid)
update(L,R,val,lson);
if(R>mid)
update(L,R,val,rson);
pushup(rt);
}
int query(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R)
return minn[rt];
int ans=INF;
int mid=(l+r)>>1;
pushdown(rt);
if(L<=mid)
ans=min(ans,query(L,R,lson));
if(R>mid)
ans=min(ans,query(L,R,rson));
return ans;
}
int main()
{
scanf("%d%d%d",&k,&n,&c);
n<<=1;
for(int i=1;i<=k;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
if(x<y)
{
a[i].s=x;
a[i].t=y-1;
a[i].m=z;
}
else
{
a[i].s=n-x;
a[i].t=n-y-1;
a[i].m=z;
}
}
sort(a+1,a+k+1,cmp);
build(1,n,1);
for(int i=1;i<=k;i++)
{
int num=min(a[i].m,query(a[i].s,a[i].t,1,n,1));
update(a[i].s,a[i].t,-num,1,n,1);
ans+=num;
}
printf("%d",ans);
return 0;
}