ffair

P1607 [USACO09FEB] Fair Shuttle G

可以将所有组按照右端点排序。

然后根据经典的右端点越小影响越小,可以直接贪心了,对于当前区间尽可能的多选,然后进行区间增加,每次只需要查询区间最大值即可求出最多的选择个数。

#include<cstdio>
#include<algorithm>
using namespace std;
#define Ed for(int i=h[x];~i;i=ne[i])
#define Ls(i,l,r) for(int i=l;i<r;++i)
#define Rs(i,l,r) for(int i=l;i>r;--i)
#define Le(i,l,r) for(int i=l;i<=r;++i)
#define Re(i,l,r) for(int i=l;i>=r;--i)
#define L(i,l) for(int i=0;i<l;++i)
#define E(i,l) for(int i=1;i<=l;++i)
#define W(t) while(t--)
#define Wh while
const int N=100010;
int n,c,k,l[N],r[N],v[N],f[N];
struct segment{
    int l,r,t;
    bool operator<(segment&A){
        return r<A.r;
    }
}seg[N];
void build(int p,int L,int R){
    l[p]=L,r[p]=R;
    if(L==R)return;
    int mid=L+R>>1;
    build(p<<1,L,mid);
    build(p<<1|1,mid+1,R);
}
#define pushup v[p]=max(v[p<<1],v[p<<1|1])
void pushdown(int p){
    int &ff=f[p];
    if(!ff)return;
    v[p<<1]+=ff,v[p<<1|1]+=ff;
    f[p<<1]+=ff,f[p<<1|1]+=ff;
    ff=0;
}
void update(int p,int L,int R,int val){
    if(L<=l[p]&&r[p]<=R){
        v[p]+=val,f[p]+=val;
        return;
    }
    pushdown(p);
    int mid=l[p]+r[p]>>1;
    if(L<=mid)update(p<<1,L,R,val);
    if(R>mid)update(p<<1|1,L,R,val);
    pushup;
}
int query(int p,int L,int R){
    if(L<=l[p]&&r[p]<=R)return v[p];
    pushdown(p);
    int mid=l[p]+r[p]>>1,ans=0;
    if(L<=mid)ans=query(p<<1,L,R);
    if(R>mid)ans=max(ans,query(p<<1|1,L,R));
    return ans;
}
int main(){
    #ifndef ONLINE_JUDGE
    freopen("1.in","r",stdin);
    #endif
    scanf("%d%d%d",&n,&k,&c);
    build(1,1,k);
    E(i, n){
        int a,b,c;
        scanf("%d%d%d",&a,&b,&c);
        seg[i]={a,b,c};
    }
    sort(seg+1,seg+1+n);
    int ans=0;
    E(i, n){
        auto[l,r,t]=seg[i];
        int tmp=query(1,l,r-1),tt;
        ans+=tt=min(c-tmp,t);
        if(tt)update(1,l,r-1,tt);
        // printf("%d %d %d\n",l,r,tt);
    }
    printf("%d",ans);
    return 0;
}
posted @ 2023-09-23 15:37  wscqwq  阅读(3)  评论(0编辑  收藏  举报