题目链接:poj3667
/*poj 3667 Hotel 线段树区间合并 题意: 操作1:询问是否有连续x间房间可以住,输出最左端的房间位置 操作2:顾客退房,将房间清空,表示没有人住 思路: 利用线段树建立模型,维护最大连续区间长度,其中区间长度就是对应的房间数目, 并且对应区间中最左边的端点就是ans,同时因为需要求出连续区间的最大长度, 因此每次PushUp时都将左右区间合并,lsum维护左区间的最大长度,rsum维护右区间的最大长度, sum维护区间1…N中的最大连续区间长度,cover标志对应区间是否为空(没有住客) */ #include#include #include using namespace std; #define lson l, m, rt<<1 #define rson m+1, r, rt<<1|1 const int N = 150000; int cover[N<<2]; int llen[N<<2],rlen[N<<2],mlen[N<<2]; void build(int l, int r, int rt) { llen[rt] = rlen[rt] = mlen[rt] = r - l + 1; cover[rt] = -1; if(l == r) return; int m = (l + r) >> 1; build(lson); build(rson); } void pushdown(int rt, int m)//更新子节点 { if(cover[rt] != -1) { llen[rt<<1] = rlen[rt<<1] = mlen[rt<<1] = cover[rt] 0 : m - (m>>1); llen[rt<<1|1] = rlen[rt<<1|1] = mlen[rt<<1|1] = cover[rt] 0 : (m>>1); cover[rt<<1] = cover[rt<<1|1] = cover[rt]; cover[rt] = -1; } } void pushup(int rt, int m)//更新父节点 { llen[rt] = llen[rt<<1]; rlen[rt] = rlen[rt<<1|1]; if(llen[rt] == m - (m>>1)) llen[rt] += llen[rt<<1|1]; if(rlen[rt] == (m>>1)) rlen[rt] += rlen[rt<<1]; mlen[rt] = max(llen[rt<<1|1] + rlen[rt<<1], max(mlen[rt<<1], mlen[rt<<1|1])); } void update(int L, int R, int c, int l, int r, int rt) { if(L <= l && r <= R) { llen[rt] = rlen[rt] = mlen[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 num, int l, int r, int rt) { if(l == r) return l; pushdown(rt, r-l+1); int m = (l+r) >> 1; if(mlen[rt<<1] >= num) // 左连续区间长度 return query(num, lson); else if(rlen[rt<<1] + llen[rt<<1|1] >= num) // 左区间右半部分与右区间左半部分长度 return m - rlen[rt<<1] + 1; return query(num, rson); } int main() { int n,m; while(~scanf("%d%d",&n,&m)) { build(1, n ,1); while(m--) { int op,x,y; scanf("%d",&op); if(op == 1) { scanf("%d",&x); if(mlen[1] < x) puts("0"); else { int ans = query(x, 1, n, 1); printf("%d\n",ans); update(ans, ans + x - 1, 1, 1, n, 1); } } if(op == 2) { scanf("%d%d",&x,&y); update(x, x+y-1, 0, 1, n, 1); } } } return 0; }