[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 }
View Code

 

posted @ 2016-06-18 15:53  czllgzmzl  阅读(221)  评论(0编辑  收藏  举报