【poj3667】【线段树】Hotel
来源:互联网 发布:seo网站建设 编辑:程序博客网 时间:2024/05/23 01:51
关于区间合并的线段树。
要求的是满足一个条件的最左边的位置。
所以可以维护一个sum,suml,sumr分别表示一段区间内空房间的数目,从最左边开始的数目,以及从最右边开始的数目,在pushup的时候需要对区间进行合并,这样在考虑询问的时候,根据维护的信息,优先考虑左边房间就行了。
代码:
#include<cstdio>#include<cstring>#define lson l,m,rt << 1#define rson m + 1,r,rt << 1 | 1using namespace std;const int maxn = 50000 + 10;int suml[maxn<<2],sumr[maxn<<2],sum[maxn<<2];int cover[maxn<<2];int n,m;void init(){freopen("poj3667.in","r",stdin);freopen("poj3667.out","w",stdout);}void build(int l,int r,int rt){sum[rt] = suml[rt] = sumr[rt] = r - l + 1;cover[rt] = -1;if(l == r)return;int m = (l + r) >> 1;build(lson);build(rson);}int max(int a,int b){return a > b ? a : b;}void pushup(int rt,int m){suml[rt] = suml[rt<<1];sumr[rt] = sumr[rt<<1|1];if(suml[rt] == m - (m >> 1))suml[rt] += suml[rt<<1|1];if(sumr[rt] == (m >> 1))sumr[rt] += sumr[rt<<1];sum[rt] = max(suml[rt<<1|1] + sumr[rt<<1],max(sum[rt<<1],sum[rt<<1|1]));}void pushdown(int rt,int m){if(cover[rt] != -1){cover[rt<<1] = cover[rt<<1|1] = cover[rt];sum[rt<<1] = suml[rt<<1] = sumr[rt<<1] = cover[rt] ? 0 : m - (m >> 1);sum[rt<<1|1] = suml[rt<<1|1] = sumr[rt<<1|1] = cover[rt] ? 0 : (m >> 1);cover[rt] = -1;}}void update(int L,int R,int c,int l,int r,int rt){if(L <= l && r <= R){sum[rt] = suml[rt] = sumr[rt] = c ? 0 : r - l + 1;cover[rt] = c;return;}pushdown(rt,r - l + 1);int m = (l + r) >> 1;if(L <= m)update(L,R,c,lson);if(m < R)update(L,R,c,rson);pushup(rt,r - l + 1);}int query(int tot,int l,int r,int rt){if(l == r)return l;pushdown(rt,r - l + 1);int m = (l + r) >> 1;if(sum[rt<<1] >= tot)return query(tot,lson);else if(sumr[rt<<1] + suml[rt<<1|1] >= tot)return m - sumr[rt<<1] + 1;return query(tot,rson);}void readdata(){memset(cover,-1,sizeof(cover));scanf("%d%d",&n,&m);build(1,n,1);for(int i = 1;i <= m;i++){int op,d;scanf("%d",&op);if(op == 1){scanf("%d",&d);if(sum[1] < d)puts("0");else{int tmp = query(d,1,n,1);printf("%d\n",tmp);update(tmp,tmp + d - 1,1,1,n,1);}}else{int x;scanf("%d%d",&x,&d);update(x,x + d - 1,0,1,n,1);}}}int main(){init();readdata();return 0;}
- 【poj3667】【线段树】Hotel
- 【线段树】Hotel POJ3667
- POJ3667 Hotel(线段树)
- 线段树 poj3667 Hotel
- 【POJ3667】Hotel-线段树
- #POJ3667#Hotel(线段树)
- poj3667 Hotel(线段树)
- 线段树典型例题--poj3667 hotel
- POJ3667——Hotel(线段树)
- poj3667 Hotel (线段树区间合并)
- POJ3667:Hotel(线段树区间合并)
- poj3667 Hotel 线段树 区间合并
- POJ3667-Hotel-线段树区间合并(模板)
- 【随便做做|线段树】POJ3667 Hotel
- poj3667-Hotel 线段树区间合并
- poj3667 Hotel (线段树+区间合并)
- poj3667 Hotel (线段树--区间合并)转自网络
- poj3667 Hotel 线段树延迟更新 区间合并
- View 和 ViewGroup的分析
- android listView & 下拉刷新 & 仿通讯录的alpha
- HTML5之----Xcode iOS PhoneGap入门
- zoom 放大縮小屬性
- 双向链表的简单操作
- 【poj3667】【线段树】Hotel
- 在Hadoop上运行SQL:程序员需知晓的13种数据工具
- ubuntu luci 安装编译
- CheckBoxList 獲取選中的值或判斷被選中項
- [DLL]使用def文件从dll导出
- oracle number sequence 和 java.util.Long范围关系oracle sequence的取值范围是
- OpenErp学习笔记
- uploadify 上传大文件 出现的 HTTP error 问题的方法
- js 网页列印