P2052【USACO 2013 January Gold】座位
来源:互联网 发布:杀女婴知乎 编辑:程序博客网 时间:2024/06/06 00:47
问题描述
奶牛们开了一家餐馆。该餐馆里有N(1 <= N <= 500,000)个排成一列的座位(编号1到N),编号越小的座位越靠近窗户。早晨开业时,座位都是空的。
今天餐馆里发生了M(1 <= M <= 300,000)个事件,这些事件总共分两类:
1.一伙人一起来就餐,该伙人共P(1 <= p <= N)个人,这伙人想坐在一段连续的位置上就餐,如果能坐下,他们希望座位尽量靠近窗户。如果无法坐下,他们会马上离开。
2.坐在a号到b号(1 <= a <= b <= N) 这连续一段座位的客人用餐完毕后离开了。
请帮贝西计算今天有多少伙人因为没有满足他们要求的座位而离开了。
输入格式
第一行,两个空格间隔的整数N和M
接下来M行,按时间先后描述了今天发生的事件:
字母A和一个整数P表示一伙P个人到达的餐馆。
字母L和两个整数a,b表示a到b这一段位置的客人离开了。
输出格式
一个整数,表示所求的结果
样例输入
10 4
A 6
L 2 4
A 5
A 2
样例输出
1
题解
线段树,维护区间最大连续空位的长度。注意1.查询连续区间长度a时要从先找左再找中间再找右边,满足标号最小。2.数组大小。3.细节细节!
代码
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <stdio.h>using namespace std;#define maxn 500001struct node{ int l,r,a,b,lazy,max1;};node tree[maxn*20];int n,m;int ans;void update(int p){ int ls=p<<1,rs=p<<1|1; int le=tree[ls].b-tree[ls].a+1,re=tree[rs].b-tree[rs].a+1; if(le==tree[ls].l) tree[p].l=le+tree[rs].l; else tree[p].l=tree[ls].l; if(re==tree[rs].r) tree[p].r=re+tree[ls].r; else tree[p].r=tree[rs].r; tree[p].max1=max(tree[ls].max1,max(tree[rs].max1,tree[ls].r+tree[rs].l));}void bt(int p,int x,int y){ tree[p].a=x;tree[p].b=y; if(x==y) { tree[p].l=tree[p].r=tree[p].max1=1; return ; } bt(p<<1,x,(x+y)>>1); bt(p<<1|1,((x+y)>>1)+1,y); tree[p].l=tree[p].r=tree[p].max1=y-x+1;}void pd(int s){ int ls=s<<1,rs=s<<1|1; tree[ls].lazy=tree[rs].lazy=tree[s].lazy; if(tree[s].lazy==1) { tree[ls].l=tree[ls].r=tree[ls].max1=0; tree[rs].r=tree[rs].l=tree[rs].max1=0; } else { tree[ls].l=tree[ls].r=tree[ls].max1=tree[ls].b-tree[ls].a+1; tree[rs].r=tree[rs].l=tree[rs].max1=tree[rs].b-tree[rs].a+1; } tree[s].lazy=0;}int check;int find(int p,int d)//先查左边再查右边最后查中间{ int ls=p<<1,rs=p<<1|1; if(tree[p].l>=d) return tree[p].a; if(tree[p].max1<d) return -1; if(tree[p].lazy) pd(p); if(tree[ls].max1>=d) return find(ls,d); if(tree[ls].r+tree[rs].l>=d) return tree[ls].b-tree[ls].r+1; if(tree[rs].max1>=d) return find(rs,d);}void arrive(int s,int x,int y){ if(x<=tree[s].a&&tree[s].b<=y){ tree[s].l=tree[s].r=tree[s].max1=0; tree[s].lazy=1; return; } if(tree[s].lazy)pd(s); int mid=(tree[s].a+tree[s].b)>>1; if(x<=mid) arrive(s<<1,x,y); if(y>mid) arrive(s<<1|1,x,y); update(s);}void leave(int s,int x,int y){ if(x<=tree[s].a&&tree[s].b<=y){ tree[s].l=tree[s].r=tree[s].max1=tree[s].b-tree[s].a+1; tree[s].lazy=2; return; } if(tree[s].lazy)pd(s); int mid=(tree[s].a+tree[s].b)>>1; if(x<=mid) leave(s<<1,x,y); if(y>mid) leave(s<<1|1,x,y); update(s);}int main(){ int i,j,k; scanf("%d%d",&n,&m); bt(1,1,n); char c; for(i=1;i<=m;i++) { int x,y,z; cin>>c; if(c=='A') { scanf("%d",&x); z=find(1,x); if(z==-1) ans++; else arrive(1,z,z+x-1); } else { scanf("%d%d",&x,&y); leave(1,x,y); } } cout<<ans;}
阅读全文
0 0
- P2052【USACO 2013 January Gold】座位
- 【USACO 2013 January Gold】座位 --线段树
- 【USACO 2013 January Gold】奶牛排队
- 【BZOJ3050】【USACO 2013 Jan Gold金组】坐座位 Seating
- USACO 2012 January Contest, Gold Division Solution
- [USACO 2012 January Gold] Video Game Combos
- P2770【USACO 2014 January Gold】难度系数
- USACO 2017 January Contest, Gold Problem 1. Balanced Photo
- USACO 2017 January Contest, Gold Problem 2. Hoof, Paper, Scissors
- 【USACO 2013 February Gold】出租车
- BSOJ: 1708 【USACO 2008 January Gold】Cell Phone Network手机网络
- 【USACO 2013 February Gold】分割农场
- 【USACO 2013 March Gold】奶牛逃跑
- 【USACO 2013 February Gold】旅行线路
- [USACO NOV06 GOLD]路障
- [usaco gold 2016.1]无线电通信
- [USACO GOLD] 选做
- USACO January 2014 Bronze Level
- Struts2国际化和数据验证
- 暑期任务----急速从入门到放弃
- Android Wi-Fi Wi-Fi Protected Setup(WPS)
- 破损的键盘(链表)
- Bayes & Decision Tree Classifiers
- P2052【USACO 2013 January Gold】座位
- Android Wi-Fi 无缝漫游 Seamless Roaming
- checkbox 选中和取消切换没效果
- BZOJ4003 [JLOI2015]城池攻占
- 在网页中放不出来MP4
- 二叉树遍历模板(前序,中序,后序)
- java图片处理(混合层叠图片)
- 人机猜拳
- seleniuim面试题(testclass网)