题解 2018寒假训练3 D.酒店

zhouwc

2018-02-25 09:37:31

Personal

问题 D: 酒店 时间限制: 1 Sec 内存限制: 128 MB [提交][状态][讨论版] 题目描述 A城市有个超级大酒店,住房部只有一层,只向南,但房间有N个(编号1, 2 .. N)。刚开始所有房间都是空的,但酒店肯定会有人来住宿,有些房间就要被入住。但客人经常会问一个问题,最长连续的空房间是多少,因为客人想连续的住在一起。于是,有下列三个操作: 1 a b:表示从房间a开始连续b个房间,将被入住(不管有没有人已经入住) 2 a b:表示从房间a开始连续b个房间,将清空入住(不管有没有人入住) 3:表示询问当前最长连续的空房间是多少? 对于3的询问,输出相应答案。 输入 首先输入N和P, N如问题描述,P表示有多少个操作 然后输入P个操作 输出 对于第三种操作,输出相应答案 样例输入 12 10 3 1 2 3 1 9 4 3 2 2 1 3 2 9 2 3 2 3 2 3 样例输出 12 4 4 6 10 提示 【数据规模和约定】 3<=N<=16,000 3<=P<=200,000 题解 班长的代码与思路。fyk大佬的讲解与修改。 ```cpp #include <cstdio> #include <algorithm> using namespace std; const int N=100005; int n,m,op,l,r; int mx[N],lmx[N],rmx[N],col[N]; void build(int l,int r,int id){ if(l==r){ mx[id]=lmx[id]=rmx[id]=1; col[id]=1; return; } int mid=(l+r)>>1; build(l,mid,id<<1); build(mid+1,r,id<<1|1); mx[id]=lmx[id]=rmx[id]=r-l+1; col[id]=1; } void update(int L,int R,int k,int l,int r,int id){ if(L<=l&&r<=R){ col[id]=k; if(k==1)mx[id]=lmx[id]=rmx[id]=r-l+1; else mx[id]=lmx[id]=rmx[id]=0; return; } int mid=(l+r)>>1; if(col[id]!=-1)col[id<<1]=col[id<<1|1]=col[id]; if(col[id]==1){ mx[id<<1]=lmx[id<<1]=rmx[id<<1]=mid-l+1; mx[id<<1|1]=lmx[id<<1|1]=rmx[id<<1|1]=r-mid; } if(col[id]==0){ mx[id<<1]=lmx[id<<1]=rmx[id<<1]=0; mx[id<<1|1]=lmx[id<<1|1]=rmx[id<<1|1]=0; } col[id]=-1; if(L<=mid)update(L,R,k,l,mid,id<<1); if(mid<R) update(L,R,k,mid+1,r,id<<1|1); mx[id]=max(max(mx[id<<1],mx[id<<1|1]),rmx[id<<1]+lmx[id<<1|1]); if(col[id<<1]==col[id<<1|1])col[id]=col[id<<1]; if(col[id<<1]==1)lmx[id]=mx[id<<1]+lmx[id<<1|1]; if(col[id<<1]==0)lmx[id]=0; if(col[id<<1]==-1)lmx[id]=lmx[id<<1]; if(col[id<<1|1]==1)rmx[id]=rmx[id<<1]+mx[id<<1|1]; if(col[id<<1|1]==0)rmx[id]=0; if(col[id<<1|1]==-1)rmx[id]=rmx[id<<1|1]; } int main(){ scanf("%d%d",&n,&m); build(1,n,1); for(int i=1;i<=m;i++){ scanf("%d",&op); if(op==3)printf("%d\n",mx[1]); else{ scanf("%d%d",&l,&r);r=l+r-1; update(l,r,op-1,1,n,1); } } return 0; } ```