题目链接:http://poj.org/problem?id=1823
题意:
有三种操作
- 1 A M 表示从 A 到 A+M-1 住进M个人
- 2 A M 表示从 A 到 A+M-1 搬到M个人
- 3 表示查询这个hotel 连续的空房间有多少
题解:
区间合并问题
线段树维护从左端/右端/整段最多连续0的个数
col标记整段覆盖情况,-1表示全空,1表示全满,0表示不空不满
维护起来比较复杂,看代码吧
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define getmid int m=(t[rt].l+t[rt].r)>>1
#define LL long long
#define L(rt) (rt<<1)
#define R(rt) (rt<<1|1)
const int N=16050;
int n,m;
struct segtree
{
int Max,lmax,rmax,l,r,col;
//col 1->full -1->empty 0->not full not empty
}t[N<<2];
void Build(int l,int r,int rt)
{
t[rt].l=l;
t[rt].r=r;
if(l==r) return;
int m=(l+r)>>1;
Build(l,m,L(rt));
Build(m+1,r,R(rt));
}
void Pushdown(int op,int rt)
{
if(op==-1)
{
t[rt].col=0;
t[L(rt)].col=op;
t[L(rt)].Max=t[L(rt)].lmax=t[L(rt)].rmax=t[L(rt)].r-t[L(rt)].l+1;
t[R(rt)].col=op;
t[R(rt)].Max=t[R(rt)].lmax=t[R(rt)].rmax=t[R(rt)].r-t[R(rt)].l+1;
}
else
{
t[rt].col=0;
t[L(rt)].col=op;
t[L(rt)].Max=t[L(rt)].lmax=t[L(rt)].rmax=0;
t[R(rt)].col=op;
t[R(rt)].Max=t[R(rt)].lmax=t[R(rt)].rmax=0;
}
}
void Update(int op,int L,int R,int rt)
{
if(t[rt].l==L&&t[rt].r==R)
{
t[rt].col=op;
if(op==1)
t[rt].Max=t[rt].lmax=t[rt].rmax=0;
else
t[rt].Max=t[rt].lmax=t[rt].rmax=t[rt].r-t[rt].l+1;
return;
}
if(t[rt].col==op) return;
if(t[rt].col==-op)
Pushdown(-op,rt);
getmid;
if(R<=m) Update(op,L,R,L(rt));
else if(L>m) Update(op,L,R,R(rt));
else
{
Update(op,L,m,L(rt));
Update(op,m+1,R,R(rt));
}
if(t[L(rt)].col==-1)
t[rt].lmax=t[L(rt)].Max+t[R(rt)].lmax;
else
t[rt].lmax=t[L(rt)].lmax;
if(t[R(rt)].col==-1)
t[rt].rmax=t[R(rt)].Max+t[L(rt)].rmax;
else
t[rt].rmax=t[R(rt)].rmax;
int mid=t[L(rt)].rmax+t[R(rt)].lmax;
int a=max(t[rt].lmax,t[rt].rmax);
int b=max(t[L(rt)].Max,t[R(rt)].Max);
t[rt].Max=max(max(a,b),mid);
if(t[L(rt)].col==t[R(rt)].col)
t[rt].col=t[L(rt)].col;
}
int main()
{
scanf("%d%d",&n,&m);
Build(1,n,1);
t[1].col=-1;
t[1].Max=n;
int a,b,c;
while(m--)
{
scanf("%d",&c);
if(c==1)
{
scanf("%d%d",&a,&b);
Update(1,a,a+b-1,1);
}
else if(c==2)
{
scanf("%d%d",&a,&b);
Update(-1,a,a+b-1,1);
}
else
printf("%d\n",t[1].Max);
}
return 0;
}