[USACO 09FEB]Fair Shuttle

Description

逛逛集市,兑兑奖品,看看节目对农夫约翰来说不算什么,可是他的奶牛们非常缺乏锻炼——如果要逛完一整天的集市,他们一定会筋疲力尽的。所以为了让 奶牛们也能愉快地逛集市,约翰准备让奶牛们在集市上以车代步。但是,约翰木有钱,他租来的班车只能在集市上沿直线跑一次,而且只能停靠N(1 ≤N≤20000)个地点(所有地点都以1到N之间的一个数字来表示)。现在奶牛们分成K(1≤K≤50000)个小组,第i 组有Mi(1 ≤Mi≤N)头奶牛,他们希望从Si跑到Ti(1 ≤Si<Ti≤N)。

由于班车容量有限,可能载不下所有想乘车的奶牛们,此时也允许小里的一部分奶牛分开乘坐班车。约翰经过调查得知班车的容量是C(1≤C≤100),请你帮助约翰计划一个尽可能满足更多奶牛愿望的方案。

Input

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

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

Output

第一行:可以坐班车的奶牛的最大头数。

Sample Input

8 15 31 5 213 14 15 8 38 14 214 15 19 12 112 15 24 6 1

Sample Output

10

Hint

班车可以把2头奶牛从1送到5,3头奶牛从5送到8,2头奶牛从8送到14,1头奶牛从9送到12,1头奶牛从13送到14,1头奶牛从14送到15。

题解

注意到可以不全部上车,那么贪心的思路就比较明确了。尽量让下车下得早的多上车,这样利益可以最大化。

我们按区间右端点排序。第i个区间[Li,Ri]显然我们要找到这个区间范围内已经累加的最大值,最大值可以用线段树维护,这里给出这种版本。

 1 #include<map>
 2 #include<set>
 3 #include<cmath>
 4 #include<ctime>
 5 #include<queue>
 6 #include<stack>
 7 #include<cstdio>
 8 #include<string>
 9 #include<vector>
10 #include<cstdlib>
11 #include<cstring>
12 #include<iostream>
13 #include<algorithm>
14 #define LL long long
15 #define RE register
16 #define IL inline
17 #define Lr (root<<1)
18 #define Rr (root<<1|1)
19  using namespace std;
20 const LL N=100000;
21
22 LL k,n,c;
23 struct tt
24 {
25     LL l,r,c;
26 }a[N+5];
27
28 LL smg[N*4+5],maxn[N*4+5];
29 LL Query(LL root,LL l,LL r,LL a,LL b);
30 void Add(LL root,LL l,LL r,LL a,LL b,LL key);
31 IL void Pushdown(LL root);
32
33 bool comp(const tt &a,const tt &b){return a.r<b.r;}
34 IL LL Min(LL a,LL b){return a<b ? a:b;}
35 IL LL Max(LL a,LL b){return a>b ? a:b;}
36
37 int main()
38 {
39     scanf("%lld%lld%lld",&k,&n,&c);
40     for (RE LL i=1;i<=k;i++)
41     {
42         scanf("%lld%lld%lld",&a[i].l,&a[i].r,&a[i].c);
43         a[i].r--;
44     }
45     sort(a+1,a+k+1,comp);
46     LL tmp,ans=0;
47     for (RE LL i=1;i<=k;i++)
48     {
49         tmp=Query(1,1,n,a[i].l,a[i].r);
50         if (tmp==c) continue;
51         ans+=Min(c-tmp,a[i].c);
52         Add(1,1,n,a[i].l,a[i].r,Min(c-tmp,a[i].c));
53     }
54     printf("%lld\n",ans);
55     return 0;
56 }
57
58 LL Query(LL root,LL l,LL r,LL a,LL b)
59 {
60     if (a<=l&&r<=b) return maxn[root];
61     Pushdown(root);
62     LL mid=(l+r)>>1;
63     LL ans=0;
64     if (mid>=a) ans=Query(Lr,l,mid,a,b);
65     if (mid<b) ans=Max(ans,Query(Rr,mid+1,r,a,b));
66     return ans;
67 }
68 void Add(LL root,LL l,LL r,LL a,LL b,LL key)
69 {
70     if (a<=l&&r<=b)
71     {
72         smg[root]+=key;
73         maxn[root]+=key;
74         return;
75     }
76     Pushdown(root);
77     LL mid=(l+r)>>1;
78     if (mid>=a) Add(Lr,l,mid,a,b,key);
79     if (mid<b) Add(Rr,mid+1,r,a,b,key);
80     maxn[root]=Max(maxn[Lr],maxn[Rr]);
81 }
82 IL void Pushdown(LL root)
83 {
84     smg[Lr]+=smg[root];maxn[Lr]+=smg[root];
85     smg[Rr]+=smg[root];maxn[Rr]+=smg[root];
86     smg[root]=0;
87 }
时间: 2024-07-29 22:57:01

[USACO 09FEB]Fair Shuttle的相关文章

[JLOI 2011]飞行路线&amp;[USACO 09FEB]Revamping Trails

Description Alice和Bob现在要乘飞机旅行,他们选择了一家相对便宜的航空公司.该航空公司一共在n个城市设有业务,设这些城市分别标记为0到n-1,一共有m种航线,每种航线连接两个城市,并且航线有一定的价格.Alice和Bob现在要从一个城市沿着航线到达另一个城市,途中可以进行转机.航空公司对他们这次旅行也推出优惠,他们可以免费在最多k种航线上搭乘飞机.那么Alice和Bob这次出行最少花费多少? Input 数据的第一行有三个整数,n,m,k,分别表示城市数,航线数和免费乘坐次数.

BZOJ1577 USACO 2009 Feb Gold 1.Fair Shuttle Solution

权限题,不给传送门啦!在学校OJ上交的.. 有些不开心,又是一道贪心,又是一个高级数据结构的模板,又是看了别人的题解还写崩了QAQ,蒟蒻不需要理由呀. 正经题解: 首先,我们可以由「显然成立法」得出,只要我们按照右端点排序,然后能塞多少就塞多少就一定是最优哒! 你们可以YY一下,如果一堆牛能下车就赶紧下是不是可以得出最优的呢,我感觉不对但是他们都说对 然后就是很基本的线段树维护区间的查询和修改了. 需要注意的一个小地方是如果是线段树修改区间右端点是要-1的,这个很显然. 下面是具体实现: 1 /

[USACO 2009 Feb Gold] Fair Shuttle (贪心+优先队列)

题目大意:有N个站点的轻轨站,有一个容量为C的列车起点在1号站点,终点在N号站点,有K组牛群,每组数量为Mi(1≤Mi≤N),行程起点和终点分别为Si和Ei(1≤Si<Ei≤N).计算最多有多少头牛可以搭乘轻轨. 一道经典的贪心题目,每当一头牛上车的时候,如果超载,我们就优先踢出去行程终点比较远的那部分牛 而 踢出哪些行程终点较远的牛 以及 哪些在车上的牛在这站到达了终点,都可以用优先队列来维护,复杂度约为 贴上代码: 1 #include <cstdio> 2 #include <

【Luogu】P1607庙会班车Fair Shuttle(线段树+贪心)

我不会做贪心题啊--贪心题啊--题啊--啊-- 我真TM菜爆了啊-- 这题就像凌乱的yyy一样,把终点排序,终点相同的按起点排序.然后维护一个查询最大值的线段树.对于一个区间[l,r],如果这个区间已经有的最大值为s,那么这个区间最多还能装下c-s头奶牛. 当然奶牛数量没那么多的话我也是没有办法 最后说一句,奶牛到终点就下车了,可以给别的奶牛腾空间,不计入个数.所以奶牛在车上的区间为[l,r-1]. #include <cstdio> #include <iostream> #in

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

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

[USACO09FEB]庙会班车Fair Shuttle

题目描述 逛逛集市,兑兑奖品,看看节目对农夫约翰来说不算什么,可是他的奶牛们非常缺乏锻炼--如果要逛完一整天的集市,他们一定会筋疲力尽的.所以为了让奶牛们也能愉快地逛集市,约翰准备让奶牛们在集市上以车代步.但是,约翰木有钱,他租来的班车只能在集市上沿直线跑一次,而且只能停靠N(1 ≤N≤20000)个地点(所有地点都以1到N之间的一个数字来表示).现在奶牛们分成K(1≤K≤50000)个小组,第i 组有Mi(1 ≤Mi≤N)头奶牛,他们希望从Si跑到Ti(1 ≤Si<Ti≤N). 由于班车容量有

bzoj1577 [USACO09FEB] Fair Shuttle

题目大意:n个站点,有m群奶牛,第i群奶牛有mi只,要从si站点出发,直到ti站点下车. 对于一群奶牛,可以不全部上车.同时在车上的奶牛数不能超过c,求最多能满足多少头奶牛的要求. 注意到可以不全部上车,那么贪心的思路就比较明确了 尽量让下车下得早的多上车,这样利益可以最大化 某些细节还是挺磨人的 1 #include<cstdio> 2 #include<cstdlib> 3 #include<iostream> 4 #include<algorithm>

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..

[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