poj 3667 Hotel(区间合并)
来源:互联网 发布:macbook u盘接口知乎 编辑:程序博客网 时间:2024/06/05 15:20
题目链接; poj 3667 Hotel
题意:有n个房间,m组询问,询问中第一个数字表示方式,1表示住人,后面的那个数表示住店的人数,2表示清空,后面跟着两个数字票p,q,表示从第p个房间开始数,q个房间清空,我们尽可能的要使人住在左边的房间且房间数必须连续,问你住店时从那个房间开始住;
#include<iostream>#include<cstdio>#define maxn 55555#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;int col[maxn<<2];//延迟标记,值为1时表示住人,0表示走人,-1表示此区间没有访问过,不用向下更新int lsum[maxn<<2],rsum[maxn<<2],msum[maxn<<2];//lsum表示区间从最左边开始到右边的连续空位,rsum为区间从最右边开始到左边的连续空位,msum表示此区间最大的连续空间void pushdown(int rt,int m){ if(col[rt]!=-1) //此区间之前被更新过,所以要向下更新 { col[rt<<1]=col[rt<<1|1]=col[rt];//把此区间的的信息传递给它的子区间 lsum[rt<<1]=rsum[rt<<1]=msum[rt<<1]=col[rt]?0:(m-(m>>1));//左儿子,两种情况,一种col为1表示住人,空位变为0,否则就是走人,空位等于区间长度 lsum[rt<<1|1]=rsum[rt<<1|1]=msum[rt<<1|1]=col[rt]?0:(m>>1);//情况与左儿子相同 col[rt]=-1; //向下女更新过了,取消标记 }}void pushup(int rt, int m){ lsum[rt]=lsum[rt<<1]; //父区间的从左开始的最大空位等于左儿子从左开始的最大空位长度 rsum[rt]=rsum[rt<<1|1];//右儿子情况与左儿子差不多 if(lsum[rt]==(m-(m>>1))) lsum[rt]+=lsum[rt<<1|1];//若左儿子的最大左空间等于区间长度,则要加上右儿子的左空间,最为父区间最大左空间的长度 if(rsum[rt]==(m>>1)) rsum[rt]+=rsum[rt<<1];//父区间的最大有空间与左儿子思想相同 msum[rt]=max(max(msum[rt<<1],msum[rt<<1|1]),rsum[rt<<1]+lsum[rt<<1|1]);//然后更新父区间整个连续空间的最大值,可能左儿子空间的最大,也可能是右儿子,也可能是左右儿子连通,他们的空间和最大}void build(int l,int r,int rt){ lsum[rt]=rsum[rt]=msum[rt]=r-l+1;//初始空间大小为区间长度 col[rt]=-1;//表示没有被标记过 if(l==r) return ; int m=(l+r)>>1; build(lson); build(rson);}int query(int p,int l,int r,int rt){ if(l==r) return l; pushdown(rt,r-l+1); //向下更新子节点 int m=(l+r)>>1; if(p<=msum[rt<<1]) return query(p,lson); //如果所需空间数比左儿子的空间数小,则住在左区间 else if(rsum[rt<<1]+lsum[rt<<1|1]>=p) return m-rsum[rt<<1]+1;//若是比左儿子的右区间与右儿子左区间的和小,则直接返回左儿子右区间的最左端 return query(p,rson);//否则在右儿子里找}void update(int L,int R,int c,int l,int r,int rt){ if(L<=l&&r<=R) { msum[rt]=lsum[rt]=rsum[rt]=c?0:r-l+1; //c为1表示住人,0,表示走人,住人则和变为0,走人则赋为区间长度 col[rt]=c;//改变区间的更新标志 return ; } pushdown(rt,r-l+1); int m=(l+r)>>1; if(L<=m) update(L,R,c,lson);//往左半部分找 if(R>m) update(L,R,c,rson);//往右半部分找 pushup(rt,r-l+1);}int main(){ int n,m; while(~scanf("%d%d",&n,&m)) { build(1,n,1); int op,a,b; while(m--) { scanf("%d",&op); if(op==1) { scanf("%d",&a); if(msum[1]<a) printf("0\n"); //若开始总区间的最大空位小于所需空位,直接输出0 else { int p = query(a,1,n,1); printf("%d\n",p); update(p,p+a-1,1,1,n,1); } } else { scanf("%d%d",&a,&b); update(a,a+b-1,0,1,n,1); } } } return 0;}
0 0
- poj 3667 Hotel(区间合并)
- POJ 3667 Hotel (区间合并)
- POJ 3667 Hotel(区间合并)
- poj 3667 Hotel 区间合并
- POJ 3667 Hotel 区间合并
- poj 3667 Hotel 区间合并
- 区间合并 POJ 3667 Hotel
- POJ 3667 Hotel(区间合并 + 区间更新)
- POJ 3667 Hotel 区间合并+区间更新
- POJ 3667 Hotel(成段更新,区间合并)
- POJ 3667 Hotel 线段树(区间合并)
- POJ 3667 - Hotel (线段树 区间合并)
- POJ 3667 Hotel(线段树区间合并)
- POJ 3667——Hotel(线段树,区间合并)
- POJ 3667 Hotel (线段树区间合并 )
- POJ 3667 Hotel (初遇线段树区间合并)
- 【POJ】 3667 hotel (线段树-区间合并)
- 【POJ】3667-Hotel(线段树的区间合并)
- 编写ActiveX控件及其打包方法
- nyoj 171 聪明的kk
- 索引分配,查找时间为1
- Linux学习笔记--结构化命令
- POJ 3371:Flesch Reading Ease 模拟
- poj 3667 Hotel(区间合并)
- 关于C语言循环结构的一些习题
- Windows下的VC++动态链接库编程
- apache2.2+mod_JK+Tomcat7+Terracotta3.7 集群
- 感知机随机梯度下降与批量梯度下降算法matlab实现
- POJ 3630 Phone List 静态字典树
- 深度优先遍历之边的分类
- 2015-2016 ACM-ICPC, NEERC, Southern Subregional Contest B - Stealing Harry Potter's Precious
- web service DEMO: C#提供web service,java进行调用asmx