洛谷—— P1204 [USACO1.2]挤牛奶Milking Cows

https://www.luogu.org/problem/show?pid=1204

题目描述

三个农民每天清晨5点起床,然后去牛棚给3头牛挤奶。第一个农民在300秒(从5点开始计时)给他的牛挤奶,一直到1000秒。第二个农民在700秒开始,在 1200秒结束。第三个农民在1500秒开始2100秒结束。期间最长的至少有一个农民在挤奶的连续时间为900秒(从300秒到1200秒),而最长的无人挤奶的连续时间(从挤奶开始一直到挤奶结束)为300秒(从1200秒到1500秒)。

你的任务是编一个程序,读入一个有N个农民(1 <= N <= 5000)挤N头牛的工作时间列表,计算以下两点(均以秒为单位):

最长至少有一人在挤奶的时间段。

最长的无人挤奶的时间段。(从有人挤奶开始算起)

输入输出格式

输入格式:

 

Line 1:

一个整数N。

Lines 2..N+1:

每行两个小于1000000的非负整数,表示一个农民的开始时刻与结束时刻。

 

输出格式:

 

一行,两个整数,即题目所要求的两个答案。

 

输入输出样例

输入样例#1:
3
300 1000
700 1200
1500 2100
输出样例#1:
900 300

说明

题目翻译来自NOCOW。

USACO Training Section 1.2

 

时间区间我用的左闭右开、

线段树区间修改,最后统计最大值、

  1 #include <cstdio>
  2 
  3 #define max(a,b) (a>b?a:b)
  4 
  5 const int N(1000005);
  6 int n,cnt,l[N],r[N],have[N];
  7 struct Tree {
  8     bool flag;
  9     int l,r,val;
 10 }tr[N<<2];
 11 
 12 #define lc (now<<1)
 13 #define rc (now<<1|1)
 14 #define mid (tr[now].l+tr[now].r>>1)
 15 void Tree_build(int now,int l,int r)
 16 {
 17     tr[now].l=l; tr[now].r=r;
 18     if(l==r)
 19     {
 20         tr[now].val=1;
 21         tr[now].flag=0;
 22         return ;
 23     }
 24     Tree_build(lc,l,mid);
 25     Tree_build(rc,mid+1,r);
 26 }
 27 void Tree_down(int now)
 28 {
 29     if(tr[now].l==tr[now].r) return ;
 30     tr[lc].flag=1; tr[lc].val=0;
 31     tr[rc].flag=1; tr[rc].val=0;
 32 }
 33 void Tree_add(int now,int l,int r)
 34 {
 35     if(tr[now].l==l&&tr[now].r==r)
 36     {
 37         tr[now].val=0;
 38         tr[now].flag=1;
 39         return ;
 40     }
 41     if(tr[now].flag) Tree_down(now);
 42     if(r<=mid) Tree_add(lc,l,r);
 43     else if(l>mid) Tree_add(rc,l,r);
 44     else Tree_add(lc,l,mid),Tree_add(rc,mid+1,r);
 45 }
 46 void Tree_push(int now)
 47 {
 48     if(tr[now].l==tr[now].r)
 49     {
 50         have[++cnt]=tr[now].val;
 51         return ;
 52     }
 53     if(tr[now].flag) Tree_down(now);
 54     Tree_push(lc); Tree_push(rc);
 55 }
 56 
 57 inline void read(int &x)
 58 {
 59     x=0; register char ch=getchar();
 60     for(;ch>'9'||ch<'0';) ch=getchar();
 61     for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
 62 }
 63 
 64 int AC()
 65 {
 66     int R=0; read(n);
 67     for(int i=1; i<=n; ++i)
 68     {
 69         read(l[i]);read(r[i]);
 70         R=max(R,r[i]);
 71     }
 72     Tree_build(1,1,R);
 73     for(int i=1; i<=n; ++i)
 74         Tree_add(1,l[i]+1,r[i]);
 75     Tree_push(1);
 76     int ans1=0,ans2=0,tmp;
 77     for(int i=1; i<=cnt; ++i)
 78     {
 79         if(have[i]) continue;
 80         tmp=1;
 81         for(int j=i+1; j<=cnt; j++)
 82         {
 83             if(have[j]==have[j-1]) tmp++;
 84             else
 85             {
 86                 if(have[j-1]) ans2=max(ans2,tmp);
 87                 else ans1=max(ans1,tmp);
 88                 tmp=1;
 89             }
 90         }
 91         if(have[cnt]) ans2=max(ans2,tmp);
 92         else ans1=max(ans1,tmp);
 93         break;
 94     }
 95     printf("%d %d\n",ans1,ans2);
 96     return 0;
 97 }
 98 
 99 int Hope=AC();
100 int main(){;}

 

posted @ 2017-09-06 18:07  Aptal丶  阅读(312)  评论(0编辑  收藏  举报