P1607 [USACO09FEB]庙会班车Fair Shuttle庙会 [线段树+贪心]

贪心:按照每组奶牛终点排序,贪心策略,能早下的先下
区间加法,区间查询

#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;
}

猜你喜欢

转载自blog.csdn.net/yjeannette/article/details/81006545