洛谷 P3071 [USACO13JAN]座位Seating-线段树区间合并(判断找,只需要最大前缀和最大后缀)+分治+贪心

P3071 [USACO13JAN]座位Seating

题目描述

To earn some extra money, the cows have opened a restaurant in their barn specializing in milkshakes. The restaurant has N seats (1 <= N <= 500,000) in a row. Initially, they are all empty.

Throughout the day, there are M different events that happen in sequence at the restaurant (1 <= M <= 300,000). The two types of events that can happen are:

  1. A party of size p arrives (1 <= p <= N). Bessie wants to seat the party in a contiguous block of p empty seats. If this is possible, she does so in the lowest position possible in the list of seats. If it is impossible, the party is turned away.

  2. A range [a,b] is given (1 <= a <= b <= N), and everybody in that range of seats leaves.

Please help Bessie count the total number of parties that are turned away over the course of the day.

有一排n个座位,m次操作。A操作:将a名客人安置到最左的连续a个空位中,没有则不操作。L操作:[a,b]的客人离开。

求A操作的失败次数。

输入输出格式

输入格式:

 

* Line 1: Two space-separated integers, N and M.

* Lines 2..M+1: Each line describes a single event. It is either a line of the form "A p" (meaning a party of size p arrives) or "L a b" (meaning that all cows in the range [a, b] leave).

 

输出格式:

 

* Line 1: The number of parties that are turned away.

 

输入输出样例

输入样例#1: 复制
10 4 
A 6 
L 2 4 
A 5 
A 2 
输出样例#1: 复制
1 

说明

There are 10 seats, and 4 events. First, a party of 6 cows arrives. Then all cows in seats 2..4 depart. Next, a party of 5 arrives, followed by a party of 2.

Party #3 is turned away. All other parties are seated.

 

代码:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 const int maxn=5e6+10;
  5 #define lson l,m,rt<<1
  6 #define rson m+1,r,rt<<1|1
  7 
  8 struct Tree{
  9     int lch,rch,val,lazy;
 10 }tree[maxn<<2];
 11 
 12 void pushup(int l,int r,int rt)
 13 {
 14     int m=(l+r)>>1;
 15     if(tree[rt<<1].val==(m-l+1)) tree[rt].lch=tree[rt<<1].val+tree[rt<<1|1].lch;
 16     else tree[rt].lch=tree[rt<<1].lch;
 17     if(tree[rt<<1|1].val==(r-m)) tree[rt].rch=tree[rt<<1|1].val+tree[rt<<1].rch;
 18     else tree[rt].rch=tree[rt<<1|1].rch;
 19     tree[rt].val=max(max(tree[rt<<1].val,tree[rt<<1|1].val),tree[rt<<1].rch+tree[rt<<1|1].lch);
 20 }
 21 
 22 void pushdown(int l,int r,int rt)
 23 {
 24     int m=(l+r)>>1;
 25     if(tree[rt].lazy){
 26         if(tree[rt].lazy==1){//清空
 27             tree[rt<<1].lazy=tree[rt<<1|1].lazy=tree[rt].lazy;
 28             tree[rt<<1].lch=tree[rt<<1].rch=tree[rt<<1].val=m-l+1;
 29             tree[rt<<1|1].lch=tree[rt<<1|1].rch=tree[rt<<1|1].val=r-m;
 30         }
 31         if(tree[rt].lazy==2){//坐满
 32             tree[rt<<1].lazy=tree[rt<<1|1].lazy=tree[rt].lazy;
 33             tree[rt<<1].lch=tree[rt<<1].rch=tree[rt<<1].val=0;
 34             tree[rt<<1|1].lch=tree[rt<<1|1].rch=tree[rt<<1|1].val=0;
 35         }
 36         tree[rt].lazy=0;
 37     }
 38 }
 39 
 40 void build(int l,int r,int rt)
 41 {
 42     tree[rt].lazy=0;
 43     if(l==r){
 44         tree[rt].lch=tree[rt].rch=tree[rt].val=1;
 45         return ;
 46     }
 47 
 48     int m=(l+r)>>1;
 49     build(lson);
 50     build(rson);
 51     pushup(l,r,rt);
 52 }
 53 
 54 void update(int L,int R,int c,int l,int r,int rt)
 55 {
 56     if(tree[rt].lazy){
 57         pushdown(l,r,rt);
 58     }
 59 
 60     if(L<=l&&r<=R){
 61         if(c==1){
 62             tree[rt].lch=tree[rt].rch=tree[rt].val=r-l+1;
 63         }
 64         if(c==2){
 65             tree[rt].lch=tree[rt].rch=tree[rt].val=0;
 66         }
 67         tree[rt].lazy=c;
 68         return ;
 69     }
 70 
 71     int m=(l+r)>>1;
 72     if(L<=m) update(L,R,c,lson);
 73     if(R> m) update(L,R,c,rson);
 74     pushup(l,r,rt);
 75 }
 76 
 77 int query(int c,int l,int r,int rt)
 78 {
 79     if(tree[rt].lazy){
 80         pushdown(l,r,rt);
 81     }
 82 
 83     if(l==r){
 84         return l;
 85     }
 86 
 87     int m=(l+r)>>1;
 88     if(tree[rt<<1].val>=c) return query(c,lson);
 89     else if(tree[rt<<1].rch+tree[rt<<1|1].lch>=c) return m-tree[rt<<1].rch+1;
 90     else return query(c,rson);
 91 }
 92 
 93 int main()
 94 {
 95     int n,m;
 96     scanf("%d%d",&n,&m);
 97     build(1,n,1);
 98     int num=0;
 99     for(int i=1;i<=m;i++){
100         char op[5];
101         scanf("%s",op);
102         if(op[0]=='A'){
103             int x;
104             scanf("%d",&x);
105             if(tree[1].val>=x){
106                 int ans=query(x,1,n,1);
107                 update(ans,ans+x-1,2,1,n,1);
108             }
109             else num++;
110         }
111         else{
112             int l,r;
113             scanf("%d%d",&l,&r);
114             update(l,r,1,1,n,1);
115         }
116     }
117     printf("%d\n",num);
118 }

 

posted @ 2019-04-18 23:50  ZERO-  阅读(301)  评论(0编辑  收藏  举报