[题解](线段树最大连续子段和)POJ_3667_Hotel
题意:1.求一个最靠左的长x的区间全部为0,并修改为1,输出这个区间的左端点
2.修改一个区间为0
实际上是维护最大连续子段和,原来也写过
大概需要维护一个左/右最大子段和,当前这段最大子段长,再维护一个lazytag
#include<iostream> #include<cstdio> #include<cstring> #define mid (l+r>>1) #define ls x<<1 #define rs x<<1|1 using namespace std; const int maxn=50009; struct node{ int l,r,mx,tg;//0全空,1全满,-1没有 }t[maxn<<2]; //inline void upd(int x,int l,int r){ // t[x].l=t[ls].l; // t[x].r=t[rs].r; //// if(t[ls].l==mid-l+1)t[x].l+=t[rs].l; //// if(t[rs].r==r-mid)t[x].r+=t[ls].r; // if(t[ls].l==(r-l+1-(r-l+1)/2))t[x].l+=t[rs].l; // if(t[rs].r==(r-l+1)/2)t[x].r+=t[ls].r; // t[x].mx=max(max(t[ls].mx,t[rs].mx),t[ls].r+t[rs].l); //} //inline void pushdown(int x,int l,int r){ // if(t[x].tg!=-1){ // t[ls].tg=t[rs].tg=t[x].tg; // t[ls].l=t[ls].r=t[ls].mx=(r-l+1-(r-l+1)/2)*t[x].tg; // t[rs].l=t[rs].r=t[rs].mx=(r-l+1)/2*t[x].tg; //// if(t[x].tg==0){ //// t[ls].l=t[ls].r=t[ls].mx=mid-l+1; //// t[rs].l=t[rs].r=t[rs].mx=r-mid; //// } //// else{ //// t[ls].l=t[ls].r=t[ls].mx=0; //// t[rs].l=t[rs].r=t[rs].mx=0; //// } // t[x].tg=-1; // } //} inline void pushdown(int x,int len){ if(t[x].tg!=-1){ t[ls].tg=t[rs].tg=t[x].tg; t[ls].mx=t[ls].l=t[ls].r=t[x].tg*(len-(len>>1)); t[rs].mx=t[rs].l=t[rs].r=t[x].tg*(len>>1); t[x].tg=-1; } } inline void upd(int x,int len){ t[x].l=t[ls].l; t[x].r=t[rs].r; if(t[x].l==len-(len>>1))t[x].l+=t[rs].l; if(t[x].r==(len>>1))t[x].r+=t[ls].r; t[x].mx=max(max(t[ls].mx,t[rs].mx),t[ls].r+t[rs].l); } void build(int x,int l,int r){ t[x].l=t[x].r=t[x].mx=r-l+1;t[x].tg=-1; if(l==r)return; build(ls,l,mid);build(rs,mid+1,r); } void change(int x,int l,int r,int L,int R,int k){ if(L<=l && r<=R){ t[x].l=t[x].r=t[x].mx= k==0?0:r-l+1; t[x].tg=k; return; } // pushdown(x,l,r); pushdown(x,r-l+1); if(L<=mid)change(ls,l,mid,L,R,k); if(R>mid)change(rs,mid+1,r,L,R,k); // upd(x,l,r); upd(x,r-l+1); } int query(int x,int l,int r,int k){ if(l==r)return 1; // pushdown(x,l,r); pushdown(x,r-l+1); if(t[ls].mx>=k)return query(ls,l,mid,k); else if(t[ls].r+t[rs].l>=k)return mid-t[ls].r+1; else return query(rs,mid+1,r,k); } int n,m; int main(){ scanf("%d%d",&n,&m); build(1,1,n); for(int i=1,op,x,y;i<=m;i++){ scanf("%d",&op); if(op==1){ scanf("%d",&x); if(t[1].mx<x)printf("0\n"); else{ int pos=query(1,1,n,x); printf("%d\n",pos); change(1,1,n,pos,pos+x-1,0); } } else{ scanf("%d%d",&x,&y); change(1,1,n,x,x+y-1,1); } } }