集市班车

集市班车

Description

逛逛集市,兑兑奖品,看看节目对农夫约翰来说不算什么,可是他的奶牛们非常缺乏锻炼——如果要逛完一整天的集市,他们一定会筋疲力尽的。所以为了让奶牛们也能愉快地逛集市,约翰准备让奶牛们在集市上以车代步。但是,约翰木有钱,他租来的班车只能在集市上沿直线跑一次,而且只能停靠N 个地点(所有地点都以1到N之间的一个数字来表示)。现在奶牛们分成K 个小组,第 i 组有Mi (1 ≤ Mi ≤ N)头奶牛,他们希望从Si跑到Ti (1 ≤ Si < Ti ≤ N)。由于班车容量有限,可能载不下所有想乘车的奶牛们,此时也允许小组里的一部分奶牛分开乘坐班车。约翰经过调查得知班车的容量是C ,请你帮助约翰计划一个尽可能满足更多奶牛愿望的方案。

Input

第一行:包括三个整数:K,N和C,彼此用空格隔开。

第二行到K + 1行:在第i + 1行,将会告诉你第i组奶牛的信息:Si,Ei和Mi,彼此用空格隔开。
Output

可以坐班车的奶牛的最大头数

Sample Input

8 15 3
1 5 2
13 14 1
5 8 3
8 14 2
14 15 1
9 12 1
12 15 2
4 6 1

Sample Output

10

思路:
以右端点排序后利用线段树维护[l,r]区间中最多可以上几头牛
即query[l,r]中的最大值

void build(int L,int R,int p){
    tree[p].l=L,tree[p].r=R;
    if(L==R){tree[p].sum=0;return;} 
    int mid=(L+R)/2; 
    build(L,mid,2*p);build(mid+1,R,2*p+1);
    tree[p].sum=tree[2*p].sum+tree[2*p+1].sum; 
}
void down(int p){
    tree[2*p].add+=tree[p].add;
    tree[2*p].sum+=tree[p].add;;
    tree[2*p+1].add+=tree[p].add;
    tree[2*p+1].sum+=tree[p].add;
    tree[p].add=0;
}
void update(int l,int r,int c,int p){
    if(tree[p].add)down(p);
    if(r<tree[p].l||l>tree[p].r)return;
    if(l<=tree[p].l&&r>=tree[p].r){
        tree[p].add+=c;
        tree[p].sum+=c;
        return;
    }
    update(l,r,c,2*p);
    update(l,r,c,2*p+1);
    tree[p].sum=max(tree[p*2].sum,tree[2*p+1].sum);
}
int query(int l,int r,int p){
    if(tree[p].add)down(p);
    if(l==tree[p].l&&tree[p].r==r)return tree[p].sum;
    int mid=(tree[p].l+tree[p].r)/2;
    if(r<=mid)return query(l,r,2*p);
    if(mid<l)return query(l,r,2*p+1);
    return  max(query(l,mid,2*p),query(mid+1,r,2*p+1));
}
int main(){
    scanf("%d%d%d",&n,&m,&v);
    for(int i=1;i<=n;i++)
        scanf("%d%d%d",&s[i].l,&s[i].r,&s[i].sum);
    build(1,m,1);
    sort(s+1,s+1+n,cmp);//右端点排序
    for(int i=1;i<=n;i++){
        int l=s[i].l,r=s[i].r,sum=s[i].sum;
        int res=min(v-query(l+1,r,1),s[i].sum);
        update(l+1,r,res,1);
        ans+=res;
    }printf("%d",ans);
    return 0;
}
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值