题目链接:http://poj.org/problem?id=3667
本题也是线段树区间合并问题。和上一题LCIS类似。
题意:1 a:询问是不是有连续长度为a的空房间,有的话住进最左边
2 a b:将[a,a+b-1]的房间清空
思路:记录区间中最长的空房间
#include <iostream> #include <stdlib.h> #include <stdio.h> using namespace std; #define Maxn 50005 #define lx (x<<1) #define rx ((x<<1)|1) #define MID ((l + r)>>1) int A[Maxn]; //记录连续空房间的最大个数 int midSum[Maxn<<2]; int leftSum[Maxn<<2]; int rightSum[Maxn<<2]; //标记是否被覆盖 int cover[Maxn<<2]; void pushDown(int l,int r,int x) { if(cover[x]!=-1) { int m = (r - l + 1); cover[lx] = cover[rx] = cover[x]; //被占用 if(cover[x] == 1) { midSum[lx] = leftSum[lx] = rightSum[lx] = 0; midSum[rx] = leftSum[rx] = rightSum[rx] = 0; } //未被占用 else { midSum[lx] = leftSum[lx] = rightSum[lx] = m - (m>>1); midSum[rx] = leftSum[rx] = rightSum[rx] = (m>>1); } cover[x] = -1; } } void pushUp(int l,int r,int x) { int m = r - l + 1; leftSum[x] = leftSum[lx]; rightSum[x] = rightSum[rx]; if(leftSum[x] == m-(m>>1)) leftSum[x] += leftSum[rx]; if(rightSum[x] == (m >> 1)) rightSum[x] += rightSum[lx]; midSum[x] = max(leftSum[rx] + rightSum[lx],max(midSum[lx],midSum[rx])); } void build(int l,int r,int x) { cover[x] = -1; midSum[x] = leftSum[x] = rightSum[x] = (r - l + 1); if(l == r) return; build(l,MID,lx); build(MID+1,r,rx); } void update(int L,int R,int d,int l,int r,int x) { if(L<=l && r<=R) { cover[x] = d; if(d == 0) midSum[x] = leftSum[x] = rightSum[x] = r-l+1; else midSum[x] = leftSum[x] = rightSum[x] = 0; return; } pushDown(l,r,x); if(L<=MID) update(L,R,d,l,MID,lx); if(MID+1<=R) update(L,R,d,MID+1,r,rx); pushUp(l,r,x); } int query(int w,int l,int r,int x) { if (l == r) return l; pushDown(l,r,x); if(w<=midSum[lx]) return query(w,l,MID,lx); else if(w<=rightSum[lx] + leftSum[rx]) return (MID - rightSum[lx] + 1); else return query(w,MID+1,r,rx); } int main() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); #endif int n,m; int op; int d,x; scanf(" %d %d",&n,&m); build(1,n,1); for(int i=0;i<m;i++) { scanf(" %d",&op); if(op == 1) { scanf(" %d",&d); if(midSum[1]<d) puts("0"); else { int p = query(d,1,n,1); printf("%d\n",p); update(p,p+d-1,1,1,n,1); } } else { scanf(" %d %d",&x,&d); update(x,x+d-1,0,1,n,1); } } return 0; }