贪心:按照每组奶牛终点排序,贪心策略,能早下的先下
区间加法,区间查询
#include<bits/stdc++.h>
using namespace std;
int n,k,C;
struct Pep{
int s,t,c;
}p[50005];
struct Tree{
int l,r,mx,num;
}tre[20005<<2];//
bool cmp(Pep x,Pep y){
if(x.t<y.t) return 1;
else if(x.t==y.t)
return x.s<y.s;
return 0;
}
void pushup(int rt)
{
tre[rt].mx=max(tre[rt<<1].mx,tre[rt<<1|1].mx);
}
void build(int rt,int L,int R)
{
tre[rt].l=L;//建树的时候 不要先把L==R放前面,否则这个编号对应区间只有一个数的,无法记录L和R了
tre[rt].r=R;
if(L==R)
{
tre[rt].mx=0;
tre[rt].num=0;
return ;
}
int mid=(L+R)>>1;
build(rt<<1,L,mid);
build(rt<<1|1,mid+1,R);
pushup(rt);
}
void pushdown(int rt)
{
if(tre[rt].num)//记不得是什么了->有没有标记,有的话就下传
{
int fg=tre[rt].num;
tre[rt<<1].num+=fg;
tre[rt<<1|1].num+=fg;
tre[rt<<1].mx+=fg;
tre[rt<<1|1].mx+=fg;
tre[rt].num=0;
}
}
void update(int rt,int L,int R,int k)
{
if(L<=tre[rt].l && R>=tre[rt].r)
{
tre[rt].num+=k;
tre[rt].mx+=k;
return;//少
}
pushdown(rt);
int mid=(tre[rt].l+tre[rt].r)>>1;
if(L<=mid)//少=
update(rt<<1,L,R,k);
if(R>mid)
update(rt<<1|1,L,R,k);
pushup(rt);
}
int query(int rt,int L,int R)
{
if(L<=tre[rt].l && R>=tre[rt].r)
{
return tre[rt].mx;
}
pushdown(rt);
int mid=(tre[rt].l+tre[rt].r)>>1;
int qmx=0;
if(L<=mid)
qmx=max(qmx,query(rt<<1,L,R));
if(R>mid)
qmx=max(qmx,query(rt<<1|1,L,R));
return qmx;
}
int main()
{
scanf("%d%d%d",&k,&n,&C);
for(int i=1;i<=k;i++)
{
scanf("%d%d%d",&p[i].s,&p[i].t,&p[i].c);
}
sort(p+1,p+k+1,cmp);
build(1,1,n);
// for(int i=1;i<=2*n-1;i++)
// {
// cout<<i<<","<<tre[i].l<<","<<tre[i].r<<endl;
// }
int ans=0;
for(int i=1;i<=k;i++)
{
int tc=query(1,p[i].s,p[i].t);//查询这个区间的最大值
// 如果这个最大值<C ,那么累加操作
if((C-tc)>0)
{
update(1,p[i].s,p[i].t-1,min(p[i].c,C-tc)); //
ans+=min(p[i].c,C-tc);
}
}
cout<<ans<<endl;
}