POJ 3667 Hotel 线段树(区间合并)
来源:互联网 发布:海贼王霸气败笔知乎 编辑:程序博客网 时间:2024/05/14 17:02
链接:http://poj.org/problem?id=3667
题意:一家旅馆,不断有人入住,退房。入住的人要求房号连续,退房是连续房号的房间退掉。
思路:线段树LAZY-TAG+区间合并。相比于最基本的线段树,这道题每个“段”中多了三个标记。
lsum:从最左端开始连续空房。rsum:从最右端开始连续空房。sum:该段中最长连续空房。s是LAZY-TAG,-1表示无操作,0表示清空操作,1表示入住操作。
代码:
#include <iostream>#include <cstdio>#include <cstring>#include <cctype>#include <cstdlib>#include <cmath>#include <map>#include <set>#include <queue>#include <stack>#include <vector>#include <ctype.h>#include <algorithm>#include <string>#define PI acos(-1.0)#define maxn 50005#define INF 1<<25#define MAX 0x7fffffff#define mem(a,b) memset(a,b,sizeof(a))#define f(i,a,b) for(i=a;i<b;i++)typedef long long ll;using namespace std;struct Line{ int l,r; int lsum,rsum,sum; int s; int mid() { return (l+r)>>1; } int len() { return r-l+1; }} line[maxn*4];int build_tree(int l,int r,int step){ line[step].l=l; line[step].r=r; line[step].lsum=line[step].rsum=line[step].sum=line[step].len(); line[step].s=-1; if(l==r) return 0; build_tree(l,line[step].mid(),step<<1); build_tree(line[step].mid()+1,r,step<<1|1);}int downward(int step){ if(line[step].s!=-1) { line[step<<1].s=line[step<<1|1].s=line[step].s; if(line[step].s==0) { line[step<<1].lsum=line[step<<1].rsum=line[step<<1].sum=line[step<<1].len(); line[step<<1|1].lsum=line[step<<1|1].rsum=line[step<<1|1].sum=line[step<<1|1].len(); } else { line[step<<1].lsum=line[step<<1].rsum=line[step<<1].sum=0; line[step<<1|1].lsum=line[step<<1|1].rsum=line[step<<1|1].sum=0; } line[step].s=-1; }}int upward(int step){ line[step].lsum=line[step<<1].lsum+((line[step<<1].lsum==line[step<<1].len())?line[step<<1|1].lsum:0); line[step].rsum=line[step<<1|1].rsum+(line[step<<1|1].rsum==line[step<<1|1].len()?line[step<<1].rsum:0); line[step].sum=max(line[step<<1].rsum+line[step<<1|1].lsum,max(line[step<<1].sum,line[step<<1|1].sum));}int query(int t,int step){ if(line[step].l==line[step].r) return 1; downward(step); if(line[step<<1].sum>=t) return query(t,step<<1); else if(line[step<<1].rsum+line[step<<1|1].lsum>=t) return line[step].mid()-line[step<<1].rsum+1; else return query(t,step<<1|1);}int update(int l,int r,int step,int t){ if(l<=line[step].l&&r>=line[step].r) { line[step].s=t; if(t==1) line[step].lsum=line[step].rsum=line[step].sum=0; else line[step].lsum=line[step].rsum=line[step].sum=line[step].len(); return 0; } downward(step); if(line[step].mid()>=r) update(l,r,step<<1,t); else if(line[step].mid()<l) update(l,r,step<<1|1,t); else { update(l,line[step].mid(),step<<1,t); update(line[step].mid()+1,r,step<<1|1,t); } upward(step);}int main(){ int tot,tt; scanf("%d%d",&tot,&tt); build_tree(1,tot,1); for(int i=0; i<tt; i++) { int s,L,ls; scanf("%d",&s); if(s==1) { scanf("%d",&L); if(L>line[1].sum) printf("0\n"); else { int ans=query(L,1); printf("%d\n",ans); update(ans,ans+L-1,1,1); } } else { scanf("%d%d",&ls,&L); update(ls,ls+L-1,1,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 3667Hotel 线段树区间合并
- POJ 3667 - Hotel(线段树+区间合并)
- poj 3667 Hotel 线段树区间合并
- poj 3667 hotel (线段树+区间合并)
- POJ 3667 Hotel 区间合并+线段树 *
- 我们的未来在哪里
- 使用System.arraycopy()实现数组之间的复制
- [转]DataSnap服务器方法返回TClientDataSet的简易实现
- 计算机经典书籍电子书合集(适合计算机学生学习以及程序员笔试、面试)
- 中国版XBee模块,同样支持arduino,完全兼容XBee
- POJ 3667 Hotel 线段树(区间合并)
- Ibatis学习笔记
- JAVA二维数组拷贝
- 中越勘界结束,法卡山老山归了谁?
- 多层数据库应用基于Delphi DataSnap方法调用的实现(四)BLOB字段的读写
- 奇偶数分离
- 东莞“黄流”内幕:央视说对了一句话
- Use for-each liberally
- tiny6410裸机实验第3章--------------系统时钟(代码分析)