首页 > 代码库 > [USACO 09FEB]Fair Shuttle

[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 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,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 }

 

[USACO 09FEB]Fair Shuttle