[bzoj4592] [Shoi2015]脑洞治疗仪
Posted czllgzmzl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[bzoj4592] [Shoi2015]脑洞治疗仪相关的知识,希望对你有一定的参考价值。
题面无法直视系列。
中规中矩的线段树题。
涉及的操作有:区间赋值为0,计算区间内1的个数,区间赋值为1,求区间内最大的连续的1的个数。
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 using namespace std; 5 const int maxn=200233,mxnode=maxn<<1; 6 int lc[mxnode],rc[mxnode],sz[mxnode],num0[mxnode],mxl0[mxnode],mxr0[mxnode],mx0[mxnode],tot; 7 int tag[mxnode]; 8 int i,j,k,n,m,L,R,MXR,NUM,ans; 9 bool first; 10 11 int ra;char rx; 12 inline int read(){ 13 rx=getchar(),ra=0; 14 while(rx<\'0\'||rx>\'9\')rx=getchar(); 15 while(rx>=\'0\'&&rx<=\'9\')ra*=10,ra+=rx-48,rx=getchar();return ra; 16 } 17 18 inline int max(int a,int b){return a>b?a:b;} 19 inline void upd(int x,int l,int r){ 20 num0[x]=num0[l]+num0[r], 21 mxl0[x]=mxl0[l],mxr0[x]=mxr0[r]; 22 if(mxl0[l]==sz[l])mxl0[x]+=mxl0[r]; 23 if(mxr0[r]==sz[r])mxr0[x]+=mxr0[l]; 24 mx0[x]=max(max(mx0[l],mx0[r]),mxr0[l]+mxl0[r]); 25 } 26 inline void pushdown(int x){ 27 if(tag[x]==-1)return; 28 int l=lc[x],r=rc[x]; 29 if(tag[x]==0) 30 tag[l]=tag[r]=0, 31 mx0[l]=mxl0[l]=mxr0[l]=num0[l]=sz[l], 32 mx0[r]=mxl0[r]=mxr0[r]=num0[r]=sz[r]; 33 else 34 tag[l]=tag[r]=1, 35 mx0[l]=mxl0[l]=mxr0[l]=num0[l]=0, 36 mx0[r]=mxl0[r]=mxr0[r]=num0[r]=0; 37 tag[x]=-1; 38 } 39 void build(int a,int b){ 40 int x=++tot; 41 sz[x]=b-a+1,tag[x]=-1; 42 if(a==b)return; 43 int mid=a+b>>1; 44 lc[x]=tot+1,build(a,mid),rc[x]=tot+1,build(mid+1,b); 45 } 46 void cover0(int x,int a,int b){ 47 if(num0[x]==sz[x])return; 48 if(L<=a&&R>=b){ 49 tag[x]=0, 50 mx0[x]=mxl0[x]=mxr0[x]=num0[x]=sz[x]; 51 return; 52 } 53 pushdown(x); 54 int mid=a+b>>1; 55 if(L<=mid)cover0(lc[x],a,mid); 56 if(R>mid)cover0(rc[x],mid+1,b); 57 upd(x,lc[x],rc[x]); 58 } 59 void get1(int x,int a,int b){ 60 if(num0[x]==sz[x])return; 61 if(L<=a&&R>=b){ 62 NUM+=sz[x]-num0[x], 63 tag[x]=0, 64 mx0[x]=mxl0[x]=mxr0[x]=num0[x]=sz[x]; 65 return; 66 } 67 pushdown(x); 68 int mid=a+b>>1; 69 if(L<=mid)get1(lc[x],a,mid); 70 if(R>mid)get1(rc[x],mid+1,b); 71 upd(x,lc[x],rc[x]); 72 } 73 void treat(int x,int a,int b){ 74 if(!num0[x]||!NUM)return; 75 if(L<=a&&R>=b&&num0[x]<=NUM){ 76 NUM-=num0[x],tag[x]=1, 77 mx0[x]=mxl0[x]=mxr0[x]=num0[x]=0; 78 return; 79 } 80 pushdown(x); 81 int mid=a+b>>1; 82 if(L<=mid)treat(lc[x],a,mid); 83 if(R>mid)treat(rc[x],mid+1,b); 84 upd(x,lc[x],rc[x]); 85 } 86 void query(int x,int a,int b){ 87 if(L<=a&&R>=b){ 88 if(first)ans=mx0[x],MXR=mxr0[x],first=0; 89 else{ 90 ans=max(ans,max(MXR+mxl0[x],mx0[x])); 91 if(num0[x]==sz[x])MXR+=sz[x];else MXR=mxr0[x]; 92 } 93 return; 94 } 95 pushdown(x); 96 int mid=a+b>>1; 97 if(L<=mid)query(lc[x],a,mid); 98 if(R>mid)query(rc[x],mid+1,b); 99 } 100 int main(){ 101 n=read(),m=read(); 102 build(1,n);int id,x,y,x1,y1; 103 while(m--){ 104 id=read(),x=read(),y=read(); 105 if(id==0)L=x,R=y,cover0(1,1,n);//,printf(" num0:%d mxl0:%d mxr0:%d\\n",num0[1],mxl0[1],mxr0[1]); 106 if(id==1){ 107 x1=read(),y1=read(),NUM=0,L=x,R=y,get1(1,1,n); 108 L=x1,R=y1,treat(1,1,n); 109 } 110 if(id==2) 111 L=x,R=y,first=1,ans=0,query(1,1,n),printf("%d\\n",ans); 112 } 113 return 0; 114 }
以上是关于[bzoj4592] [Shoi2015]脑洞治疗仪的主要内容,如果未能解决你的问题,请参考以下文章