BZOJ1577 USACO 2009 Feb Gold 1.Fair Shuttle Solution

权限题,不给传送门啦!在学校OJ上交的..

有些不开心,又是一道贪心,又是一个高级数据结构的模板,又是看了别人的题解还写崩了QAQ,蒟蒻不需要理由呀。

正经题解:

首先,我们可以由「显然成立法」得出,只要我们按照右端点排序,然后能塞多少就塞多少就一定是最优哒!

你们可以YY一下,如果一堆牛能下车就赶紧下是不是可以得出最优的呢,我感觉不对但是他们都说对

然后就是很基本的线段树维护区间的查询和修改了。

需要注意的一个小地方是如果是线段树修改区间右端点是要-1的,这个很显然。

下面是具体实现:

  1 //OJ 1623
  2 //by Cydiater
  3 //2016.9.10
  4 #include <iostream>
  5 #include <cstdio>
  6 #include <cstring>
  7 #include <string>
  8 #include <algorithm>
  9 #include <queue>
 10 #include <map>
 11 #include <ctime>
 12 #include <cmath>
 13 #include <cstdlib>
 14 #include <iomanip>
 15 using namespace std;
 16 #define ll long long
 17 #define up(i,j,n)        for(int i=j;i<=n;i++)
 18 #define down(i,j,n)        for(int i=j;i>=n;i--)
 19 const int MAXN=2e5+5;
 20 const int oo=0x3f3f3f3f;
 21 inline int read(){
 22     char ch=getchar();int x=0,f=1;
 23     while(ch>‘9‘||ch<‘0‘){if(ch==‘-‘)f=-1;ch=getchar();}
 24     while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
 25     return x*f;
 26 }
 27 int K,N,C,x,y,v,ans=0;
 28 struct SegTree{
 29     int delta,v;
 30 }t[MAXN<<3];
 31 struct Query{
 32     int leftt,rightt,v;
 33 }q[MAXN];
 34 namespace solution{
 35     inline bool cmp(Query a,Query b){return a.rightt==b.rightt?a.leftt>b.leftt:a.rightt<b.rightt;}
 36     inline void downit(int node){
 37         t[node<<1].delta+=t[node].delta;t[node<<1|1].delta+=t[node].delta;
 38         t[node<<1].v+=t[node].delta;t[node<<1|1].v+=t[node].delta;
 39         t[node].delta=0;
 40     }
 41     void build(int leftt,int rightt,int root){
 42         if(leftt==rightt){
 43             t[root].delta=0;t[root].v=C;
 44             return;
 45         }
 46         t[root].delta=0;t[root].v=C;
 47         int mid=(leftt+rightt)>>1;
 48         build(leftt,mid,root<<1);
 49         build(mid+1,rightt,root<<1|1);
 50     }
 51     int get(int leftt,int rightt,int root){
 52         downit(root);
 53         if(leftt>y||rightt<x)        return oo;
 54         if(leftt>=x&&rightt<=y)        return t[root].v;
 55         int mid=(leftt+rightt)>>1;
 56         return min(get(leftt,mid,root<<1),get(mid+1,rightt,root<<1|1));
 57     }
 58     void updata(int leftt,int rightt,int root){
 59         downit(root);
 60         if(leftt>y||rightt<x)        return;
 61         if(leftt>=x&&rightt<=y){
 62             t[root].delta-=v;
 63             t[root].v-=v;
 64             return;
 65         }
 66         int mid=(leftt+rightt)>>1;
 67         updata(leftt,mid,root<<1);
 68         updata(mid+1,rightt,root<<1|1);
 69         t[root].v=min(t[root<<1].v,t[root<<1|1].v);
 70     }
 71     void init(){
 72         K=read();N=read();C=read();
 73         up(i,1,K){
 74             q[i].leftt=read();q[i].rightt=read()-1;q[i].v=read();
 75         }
 76         sort(q+1,q+K+1,cmp);
 77         build(1,N,1);
 78     }
 79     void slove(){
 80         up(i,1,K){
 81             x=q[i].leftt;y=q[i].rightt;v=q[i].v;
 82             int num=get(1,N,1);
 83             num=min(v,num);
 84             if(num){
 85                 ans+=num;v=num;
 86                 updata(1,N,1);
 87             }
 88         }
 89     }
 90     void output(){
 91         cout<<ans<<endl;
 92     }
 93 }
 94 int main(){
 95     //freopen("input.in","r",stdin);
 96     using namespace solution;
 97     init();
 98     slove();
 99     output();
100     return 0;
101 }

时间: 2024-09-28 20:18:13

BZOJ1577 USACO 2009 Feb Gold 1.Fair Shuttle Solution的相关文章

BZOJ1579 USACO 2009 Feb Gold 3.Revamping Trails Solution

标题效果:一个N积分m无向图边.它可以是路径k右边缘值变0,确定此时1-n最短路径长度. Sol:我以为我们考虑分层图,图复制k+1部分,每间0~k一层.代表在这个时候已经过去"自由边缘"文章编号. 层与层之间的边权值为0且为单向由上层指向下层. 这样我们以0层的1点做单源最短路径.每一层的n点的距离最小值即为答案. 仅仅只是这种点数为O(K*N),边数为O(K*M),比較慢. 我的做法是,对每一层使用heap-dijkstra算法由本层的原点更新这一层的最短路长度.然后显然能够用O(

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

【POJ3666】【USACO 2008 Feb Gold】 2.Cow Game 动规

题意:有若干个数,然后可以花费i的代价让某个数+i或者-i. 现在要求让你把序列排成不升或者不降,问最小代价. 题解: 首先可以证明,最优花费下最后所有的数都可以是现在的某个数: 证:如果两个数调整后在两个数中间,那么可以把两个数都变为其中一个数,而代价显然是等同的. 这个出来后就好做了. 我们可以先离散化一下,然后f[i][j]表示第i个数变为j时1~i这些数保持非严格单调的最小花费 转移时f[i][j]不必n*n枚举,可以维护一个前缀最优(非常水),然后O(1)转移. 然后做一遍非升,一遍非

USACO 2017 FEB Gold visitfj 最短路

题意 有一幅n*n的方格图,n <= 100,每个点上有一个值.从(1,1)出发,走到(n,n),只能走四联通.每走一步花费t,每走三步需要花费走完三步后到达格子的值.求最小花费的值. 拆点,dis[i][j]表示到达第i个点时走的总步数模3等于j时的最小花费值. #include <cstdio> #include <cstdlib> #include <cstring> #include <string> #include <algorith

道路翻新 (Revamping Trails, USACO 2009 Feb)

题意:给定m<=50000的1-n有联通的图,求最多可以使K<=20条边变为0的情况下的最短路是多少.. 思路:简单的分层图最短路,对于每个点拆成K个点.. 然后求一边最短路.. code: 1 /* 2 * Author: Yzcstc 3 * Created Time: 2014/11/5 19:25:47 4 * File Name: revamp.cpp 5 */ 6 #include<cstdio> 7 #include<iostream> 8 #includ

BZOJ1584 USACO 2009 Mar Gold 2.Cleaning Up

题目大意:有长度为N的颜色段,共有m种颜色,要将其划分成若干段,每一段的费用为这一段的不同颜色的数目的平方.求最小总费用. Sol: 首先我们注意到答案不超过n,因为我们显然可以将每一个划分为一段,答案为n. 于是每一段的颜色总数不超过sqrt(n). 因此我们维护最后出现的sqrt(n)种颜色最后出现的位置,进行转移. 总的时间复杂度为O(n*sqrt(n)). Code: #include <cmath> #include <cstdio> #include <cstri

BZOJ1585 USACO 2009 Mar Gold 3.Earthquake Damage 2

题目大意:与http://blog.csdn.net/wyfcyx_forever/article/details/39345281这个相近.只是求的是损坏节点的最小数目. Sol: 拆点最小割. S->1 c=INF 提到的点x x'->T c=INF 对于每个点x,为1或是提到的点 x->x' c=INF 对于每个点x,不为1且不是提到的点 x->x' c=1 对于原图每条边x->y x'->y c=INF y'->x c=INF 然后强大的ISAP模板水过.

【BZOJ】【3398】【USACO 2009 Feb】Bullcow 牡牛和牝牛

组合计数 排列组合求总方案数 这个可以用一个一维的动态规划解决: f[i][0]表示第i头牛是牝牛的方案数 f[i][1]表示第i头牛是牡牛的方案数 则转移为:f[i][0]=f[i-1][0]+f[i-1][1]; f[i][1]=f[i-K-1][0]+f[i-K-1][1]; 常数优化:将取模运算改为if判断语句……可从20ms降为16ms 1 /************************************************************** 2 Problem

USACO·2012·Feb Bronze &amp;&amp; 2009·Open Gold

Rope Folding [Brian Dean, 2012] 时间限制: 1 Sec 内存限制: 128 MB 题目描述 Farmer John has a long rope of length L (1 <= L <= 10,000) that he uses for various tasks around his farm. The rope has N knots tied into it at various distinct locations (1 <= N <=