poj3667 Hotel 线段树 区间合并
2014-09-02 23:59
375 查看
题意:有一个旅馆初始有n个空位置,操作一找连续空位置长度为l的最左端,如果不存在输0。操作二从[a,a+b-1]区间的位置重新
置为空。
思路:线段树区间合并。线段树维护四个信息:(1) 区间连续为空地最长长度 (2) 从区间左端连续空地最长长度 (3) 从区间右端向左
连续空的最长长度 ( 4 )区间的懒惰标记 push_down更新左右子树的4个信息,push_up用更新左右子树更新根区间。 详见代码:
置为空。
思路:线段树区间合并。线段树维护四个信息:(1) 区间连续为空地最长长度 (2) 从区间左端连续空地最长长度 (3) 从区间右端向左
连续空的最长长度 ( 4 )区间的懒惰标记 push_down更新左右子树的4个信息,push_up用更新左右子树更新根区间。 详见代码:
// file name: poj3667.cpp // // author: kereo // // create time: 2014年09月02日 星期二 20时37分55秒 // //***********************************// #include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<set> #include<map> #include<vector> #include<stack> #include<cmath> #include<algorithm> using namespace std; typedef long long ll; const int MAXN=50000+100; const int inf=0x3fffffff; #define L(x) (x<<1) #define R(x) (x<<1|1) int n,m; struct node { int l,r,c; //c=0表示这个区间全是空房,c=1表示这个区间全有人住,c=-1为初始状态 int len,ls,rs;//len为区间连续空的最长长度,ls是从区间左端向右连续空的最长长度,rs是区间右端向左连续空的最长长度 }segtree[MAXN<<2]; void build(int rt,int l,int r){ segtree[rt].l=l; segtree[rt].r=r; segtree[rt].c=-1; segtree[rt].ls=segtree[rt].rs=segtree[rt].len=r-l+1; if(l == r) return ; int mid=(l+r)>>1; build(L(rt),l,mid); build(R(rt),mid+1,r); } void push_down(int rt){ if(segtree[rt].c!=-1){ segtree[L(rt)].c=segtree[R(rt)].c=segtree[rt].c; segtree[L(rt)].ls=segtree[L(rt)].rs=segtree[L(rt)].len=segtree[rt].c ? 0 : segtree[L(rt)].r-segtree[L(rt)].l+1; segtree[R(rt)].ls=segtree[R(rt)].rs=segtree[R(rt)].len=segtree[rt].c ? 0 : segtree[R(rt)].r-segtree[R(rt)].l+1; segtree[rt].c=-1; } } void push_up(int rt){ segtree[rt].ls=segtree[L(rt)].ls; segtree[rt].rs=segtree[R(rt)].rs; int Max=max(segtree[L(rt)].len,segtree[R(rt)].len); if(segtree[rt].ls == segtree[L(rt)].r-segtree[L(rt)].l+1) segtree[rt].ls+=segtree[R(rt)].ls; if(segtree[rt].rs == segtree[R(rt)].r-segtree[R(rt)].l+1) segtree[rt].rs+=segtree[L(rt)].rs; segtree[rt].len=max(Max,segtree[L(rt)].rs+segtree[R(rt)].ls); } void update(int rt,int l,int r,int c){ if(l == segtree[rt].l && segtree[rt].r == r){ segtree[rt].c=c; segtree[rt].ls=segtree[rt].rs=segtree[rt].len= c ? 0 : segtree[rt].r-segtree[rt].l+1; return ; } push_down(rt); int mid=(segtree[rt].l+segtree[rt].r)>>1; if(l>mid) update(R(rt),l,r,c); else if(r<=mid) update(L(rt),l,r,c); else{ update(L(rt),l,mid,c); update(R(rt),mid+1,r,c); } push_up(rt); } int query(int rt,int len){ if(segtree[rt].l == segtree[rt].r) return segtree[rt].l; push_down(rt); int mid=(segtree[rt].l+segtree[rt].r)>>1; if(segtree[L(rt)].len>=len) return query(L(rt),len); else if(segtree[L(rt)].rs+segtree[R(rt)].ls>=len) return mid-segtree[L(rt)].rs+1; return query(R(rt),len); } int main() { while(~scanf("%d%d",&n,&m)){ build(1,1,n); while(m--){ int cmd,l,r; scanf("%d",&cmd); if(cmd == 1){ scanf("%d",&l); if(segtree[1].len<l) printf("0\n"); else{ int p=query(1,l); printf("%d\n",p); update(1,p,p+l-1,1); } } else{ scanf("%d%d",&l,&r); update(1,l,l+r-1,0); } } } return 0; }
相关文章推荐
- poj3667-Hotel 线段树区间合并
- POJ3667——线段树区间合并(未搞透)——Hotel
- [POJ3667]Hotel(线段树,区间合并)
- poj3667 Hotel (线段树区间合并)
- poj3667 Hotel (线段树--区间合并)转自网络
- poj3667 Hotel (线段树+区间合并)
- [线段树]poj3667 Hotel(区间合并、更新、延迟/懒惰标记
- [POJ3667]Hotel(线段树,区间合并,重写)
- poj3667 hotel(线段树区间合并)
- POJ3667:Hotel(线段树区间合并)
- poj3667 Hotel (线段树--区间合并)转自网络【2】
- poj3667 Hotel 线段树延迟更新 区间合并
- 【线段树区间合并】POJ3667-Hotel
- poj3667---Hotel 线段树区间合并,区间更新
- POJ3667-Hotel-线段树区间合并(模板)
- POJ-3667:Hotel(线段树区间合并)
- poj--3667 Hotel(线段树+区间合并)
- POJ 3667 Hotel 线段树区间合并
- POJ 3667 Hotel 线段树 区间合并
- POJ 3667 Hotel 线段树 区间合并 入门题