题目链接: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;
}