[Usaco2009 Feb]庙会捷运Fair Shuttle

Description

公交车一共经过N(1<=N<=20000)个站点,从站点1一直驶到站点N。K(1<=K<=50000)群奶牛希望搭乘这辆公交车。第i群牛一共有Mi(1<=Mi<=N)只.

他们希望从Si到Ei去。

公交车只能座C(1<=C<=100)只奶牛。而且不走重复路线,请计算这辆车最多能满足多少奶牛听要求。

注意:对于每一群奶牛,可以部分满足,也可以全部满足,也可以全部不满足。

Input

第1行: 三个整数: K,N,C。 由空格隔开。

第2..K+1行:第i+1行,告诉你第i组奶牛的信息: S_i, E_i and M_i。由空格隔开。

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

HINT

公交车可以把2头奶牛从展台1送到展台5,3头奶牛从展台5到展台8, 2头奶牛从展台8 到展台14,1头奶牛从展台9送到展台12,一头奶牛从展台13送到展台14, 一头奶牛从 14送到15。

这个题目的贪心思想显而易见,我们肯定要让下车早的奶牛上车,其次就是上车晚的。然后如何判断能上多少奶牛呢?用线段树记录每个时间点,车上还有多少空位,然后大力维护一波就可以了

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 0x7f7f7f
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
using namespace std;
inline int read(){
    int x=0,f=1;char ch=getchar();
    for (;ch<‘0‘||ch>‘9‘;ch=getchar())  if (ch==‘-‘)    f=-1;
    for (;ch>=‘0‘&&ch<=‘9‘;ch=getchar())   x=(x<<3)+(x<<1)+ch-‘0‘;
    return x*f;
}
inline void print(int x){
    if (x>=10) print(x/10);
    putchar(x%10+‘0‘);
}
const int N=5e4,M=2e4;
int n,m,K;
int root=1;
struct AC{
    int l,r,val;
    void join(int x,int y,int z){l=x,r=y,val=z;}
    bool operator <(const AC &x)const{return r!=x.r?r<x.r:l>x.l;}
}A[N+10];
struct Tree{
    #define ls (p<<1)
    #define rs ((p<<1)|1)
    int Min[M*16+10],lazy[M*16+10];
    void updata(int p){Min[p]=min(Min[ls],Min[rs]);}
    void pushdown(int p){//“懒惰”标记
        if (!lazy[p])   return;
        lazy[ls]+=lazy[p];
        lazy[rs]+=lazy[p];
        Min[ls]+=lazy[p];
        Min[rs]+=lazy[p];
        lazy[p]=0;
    }
    void build(int p,int l,int r){
        if (l==r){Min[p]=K;return;}//开始空位为K
        int mid=(l+r)>>1;
        build(ls,l,mid),build(rs,mid+1,r);
        updata(p);
    }
    int get(int p,int l,int r,int x,int y){
        pushdown(p);
        if (x<=l&&r<=y) return Min[p];
        int mid=(l+r)>>1,ans1=inf,ans2=inf;
        if (x<=mid) ans1=get(ls,l,mid,x,y);
        if (y>mid)  ans2=get(rs,mid+1,r,x,y);
        if (ans1==inf&&ans2==inf)   return 0;
        return min(ans1,ans2);
    }
    void change(int p,int l,int r,int x,int y,int t){
        pushdown(p);
        if (x<=l&&r<=y){Min[p]+=t,lazy[p]+=t;return;}
        int mid=(l+r)>>1;
        if (x<=mid) change(ls,l,mid,x,y,t);
        if (y>mid)  change(rs,mid+1,r,x,y,t);
        updata(p);
    }
}T;
int main(){
    n=read(),m=read(),K=read();
    int ans=0;
    for (int i=1,x,y,z;i<=n;i++)    x=read(),y=read()-1,z=read(),A[i].join(x,y,z);//因为在时刻r奶牛已经下车了,所以右端点要--
    sort(A+1,A+1+n);
    T.build(1,1,m);
    for (int i=1;i<=n;i++){
        int l=A[i].l,r=A[i].r;
        int tmp=min(A[i].val,T.get(1,1,m,l,r));//看看能上多少奶牛,上不了的就干脆别上了(不是vip不能挤上车)
        if (tmp)    T.change(1,1,m,l,r,-tmp),ans+=tmp;//更新,包括答案的更新和线段树的更新
    }
    printf("%d\n",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/Wolfycz/p/8411123.html

时间: 2024-12-29 11:38:45

[Usaco2009 Feb]庙会捷运Fair Shuttle的相关文章

bzoj 1577: [Usaco2009 Feb]庙会捷运Fair Shuttle——小根堆+大根堆+贪心

Description 公交车一共经过N(1<=N<=20000)个站点,从站点1一直驶到站点N.K(1<=K<=50000)群奶牛希望搭乘这辆公交车.第i群牛一共有Mi(1<=Mi<=N)只. 他们希望从Si到Ei去.公交车只能座C(1<=C<=100)只奶牛.而且不走重复路线,请计算这辆车最多能满足多少奶牛听要求.注意:对于每一群奶牛,可以部分满足,也可以全部满足,也可以全部不满足. Input 第1行: 三个整数: K,N,C. 由空格隔开. 第2..

BZOJ1577: [Usaco2009 Feb]庙会捷运Fair Shuttle

n<=20000个车站,车能同时载C<=100个人,求能满足K<=50000群人的多少个.每群人给起点终点和人数,一群人不一定要都满足. 一开始想DP,想不出,很菜. 贪心即可.如果有右端点相同的几群人,那肯定优先满足左端点大的:如果有两群人发生冲突,而我们从左到右考虑区间的话,那肯定让左边的人先满足,因为他对后面的人影响小.所以先排个序然后模拟即可.模拟用线段树. 1 #include<stdio.h> 2 #include<string.h> 3 #inclu

bzoj 1577: [Usaco2009 Feb]庙会捷运Fair Shuttle【贪心+线段树】

按结束时间排序,然后开个线段树,按照排序后的牛群贪心的选 贪心的依据是选哪头牛都是选,不如给后面的多省一点空间 #include<iostream> #include<cstdio> #include<algorithm> using namespace std; const int N=50005; int m,n,c,ans; struct xds { int l,r,mn,lz; }t[N<<1]; struct qwe { int s,t,m; }a

[bzoj1577][Usaco2009 Feb]庙会捷运Fair Shuttle_贪心_线段树

庙会捷运 Fair Shuttle bzoj-1577 Usaco-2009 Feb 题目大意:有一辆公交车从1走到n.有m群奶牛从$S_i$到$E_i$,第i群奶牛有$W_i$只.车有一个容量c.问不走回头路的情况下最多使多少奶牛到达目的地.其中,每一群奶牛不一定都拉走. 注释:$1\le n\le 2\cdot 10^4$,$1\le m\le 5\cdot 10^4$,$1\le c\le 100$. 想法:开始觉得是个裸贪心,但是没法维护.其实是这样的: 我们将所有的奶牛群排序:右端点为

BZOJ 3398: [Usaco2009 Feb]Bullcow 牡牛和牝牛( dp )

水题...忘了取模就没1A了.... --------------------------------------------------------------------------- #include<bits/stdc++.h> using namespace std; const int MOD = 5000011; const int maxn = 100009; int dp[maxn], n, k; int main() { cin >> n >> k;

【BZOJ 1579】 1579: [Usaco2009 Feb]Revamping Trails 道路升级 (最短路)

1579: [Usaco2009 Feb]Revamping Trails 道路升级 Description 每天,农夫John需要经过一些道路去检查牛棚N里面的牛. 农场上有M(1<=M<=50,000)条双向泥土道路,编号为1..M. 道路i连接牛棚P1_i和P2_i (1 <= P1_i <= N; 1 <= P2_i<= N). John需要T_i (1 <= T_i <= 1,000,000)时间单位用道路i从P1_i走到P2_i或者从P2_i 走

bzoj3398[Usaco2009 Feb]Bullcow 牡牛和牝牛*

bzoj3398[Usaco2009 Feb]Bullcow 牡牛和牝牛 题意: n头牛,其中有牡牛和牝牛两种,要求任意两只牡牛中要有k只牝牛,问几种方案.n≤100000 题解: dp.f[i]表示第i头牛为牡牛的方案数,f[i]=sigma(j,1,i-k-1)f[j],这个可以用前缀和维护,最后答案为sigma(i,1,n)f[i]. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm&g

台北捷运杀人案二审 嫌犯想道歉遭拒绝

中新网4月27日电 据台湾东森新闻云报道,犯下捷运杀人案的郑捷,台北地院一审以一罪一罚的方式判他4个死刑,台湾高等法院27日首度开庭,郑捷出庭时面无表情,通过律师表示认罪,当庭声明撤回上诉,但又说一审判他死刑违反两公约及“宪法”比例原则,坚称自己不能被判死. 带着手铐脚镣,郑捷缓缓走上阶梯,上午高院首度开庭审理,面对记者提问他不发一语,表情还是一样冷酷:案件发生至今快1年,郑捷头发长了.脸上有胡渣,但不变的是他的眼神,每次面对镜头都像是在瞪人. 年仅21岁的他犯下捷运随机杀人案,酿成4死22伤惨

Bzoj 1579: [Usaco2009 Feb]Revamping Trails 道路升级 dijkstra,堆,分层图

1579: [Usaco2009 Feb]Revamping Trails 道路升级 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1573  Solved: 428[Submit][Status][Discuss] Description 每天,农夫John需要经过一些道路去检查牛棚N里面的牛. 农场上有M(1<=M<=50,000)条双向泥土道路,编号为1..M. 道路i连接牛棚P1_i和P2_i (1 <= P1_i <= N;