View Code
#include <stdio.h> #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define maxn 16000 struct node { int llen,rlen,maxlen,c; }setree[maxn<<2]; int max(int a,int b) { return a>b?a:b; } int min(int a,int b) { return a<b?a:b; } void build(int l,int r,int rt) { setree[rt].llen=setree[rt].rlen=setree[rt].maxlen=r-l+1; setree[rt].c=-1; if(l==r) return; int m=(l+r)>>1; build(lson); build(rson); } void pushdown(int rt,int m) { if(setree[rt].c!=-1){ setree[rt<<1].llen=setree[rt<<1].rlen=setree[rt<<1].maxlen=setree[rt].c?0:m-m/2; setree[rt<<1|1].llen=setree[rt<<1|1].rlen=setree[rt<<1|1].maxlen=setree[rt].c?0:m/2; setree[rt<<1].c=setree[rt<<1|1].c=setree[rt].c; setree[rt].c=-1; } } void pushup(int rt,int m) { setree[rt].llen=setree[rt<<1].llen; if(setree[rt<<1].llen==m-m/2) setree[rt].llen+=setree[rt<<1|1].llen; setree[rt].rlen=setree[rt<<1|1].rlen; if(setree[rt<<1|1].rlen==m/2) setree[rt].rlen+=setree[rt<<1].rlen; setree[rt].maxlen=max(setree[rt<<1].rlen+setree[rt<<1|1].llen,max(setree[rt<<1].maxlen,setree[rt<<1|1].maxlen)); } void update(int l,int r,int rt,int L,int R,int c) { if(L<=l&&r<=R){ setree[rt].llen=setree[rt].rlen=setree[rt].maxlen=c?0:r-l+1; setree[rt].c=c?1:0; return; } pushdown(rt,r-l+1); int m=(l+r)>>1; if(L<=m) update(lson,L,R,c); if(R>m) update(rson,L,R,c); pushup(rt,r-l+1); } int main() { int n,p; scanf("%d%d",&n,&p); build(1,n,1); while(p--){ int op; scanf("%d",&op); if(op==1){ int a,b; scanf("%d%d",&a,&b); update(1,n,1,a,a+b-1,1); } else if(op==2){ int a,b; scanf("%d%d",&a,&b); update(1,n,1,a,a+b-1,0); } else printf("%d\n",setree[1].maxlen); } }
题目大意:一个旅馆有N(3 <= N <= 16 000)个房间,开始时均为空。现在有三种操作:
(1)从编号为a的房间开始,连续b个房间有人入住。
(2)从编号为a的房间开始,连续b个房间清空。
(3)查询N个房间里的最长连续空房数。
思路:线段树区间更新,延时标记等。