接近5k的代码啊,手都打断了
#define maxn 100003
struct NODE {
int l,r,mid,len;
int count0,max0,left0,right0;//0的个数,连续0的最大值,左边连续0的个数,右边连续0的个数
int count1,max1,left1,right1;//1的个数...
bool fill0,fill1,chg;//注意置0和置1,翻转不同
};
NODE tree[maxn*3];
int n,m;
int pa[maxn];
void fill0(int i)//将某一段置0
{
int lt=i<<1,rt=i<<1|1;
tree[i].count0=tree[i].max0=tree[i].left0=tree[i].right0=tree[i].len;
tree[i].count1=tree[i].max1=tree[i].left1=tree[i].right1=0;
tree[i].fill0=0;
if(tree[i].l+1==tree[i].r)
return;
tree[lt].fill0=tree[rt].fill0=1;
tree[lt].fill1=tree[rt].fill1=0;
tree[lt].chg=tree[rt].chg=0;
}
void fill1(int i)//将某一段置1
{
int lt=i<<1,rt=i<<1|1;
tree[i].count0=tree[i].max0=tree[i].left0=tree[i].right0=0;
tree[i].count1=tree[i].max1=tree[i].left1=tree[i].right1=tree[i].len;
tree[i].fill1=0;
if(tree[i].l+1==tree[i].r)
return ;
tree[lt].fill1=tree[rt].fill1=1;
tree[lt].fill0=tree[rt].fill0=0;
tree[lt].chg=tree[rt].chg=0;
}
void chg(int i)
{
int lt=i<<1,rt=i<<1|1;
swap(tree[i].count0,tree[i].count1);
swap(tree[i].max1,tree[i].max0);
swap(tree[i].left0,tree[i].left1);
swap(tree[i].right0,tree[i].right1);
tree[i].chg=0;
if(tree[i].l+1==tree[i].r)
return;
tree[lt].chg^=1;
tree[rt].chg^=1;
}
void updata(int i)//更新当前段
{
int lt=i<<1,rt=i<<1|1;
tree[i].count0=tree[lt].count0+tree[rt].count0;
tree[i].count1=tree[rt].count1+tree[lt].count1;
tree[i].max0=max(tree[lt].max0,tree[rt].max0);
tree[i].max0=max(tree[i].max0,tree[lt].right0+tree[rt].left0);
tree[i].left0=tree[lt].left0;
tree[i].right0=tree[rt].right0;
if(tree[lt].left0==tree[lt].len)
tree[i].left0+=tree[rt].left0;
if(tree[rt].right0==tree[rt].len)
tree[i].right0+=tree[lt].right0;
tree[i].max1 = max(tree[lt].max1,tree[rt].max1);
tree[i].max1 = max(tree[i].max1,tree[lt].right1+tree[rt].left1);
tree[i].left1=tree[lt].left1;
tree[i].right1=tree[rt].right1;
if(tree[lt].left1 == tree[lt].len)
tree[i].left1 += tree[rt].left1;
if(tree[rt].right1 == tree[rt].len)
tree[i].right1 += tree[lt].right1;
}
void down(int i)// 向下传递
{
if(tree[i].fill0)fill0(i);
if(tree[i].fill1)fill1(i);
if(tree[i].chg)chg(i);//这样可以减少修改的次数啊
}
void make(int l,int r,int i)
{
tree[i].l=l;
tree[i].r=r;
tree[i].mid=(l+r)/2;
tree[i].len=r-l;
tree[i].fill0=tree[i].fill1=tree[i].chg=0;
if(l+1==r)
{
tree[i].count0=tree[i].max0=tree[i].left0=tree[i].right0=0;
tree[i].count1=tree[i].max1=tree[i].left1=tree[i].right1=0;
if(pa[l])
tree[i].count1=tree[i].max1=tree[i].left1=tree[i].right1=1;
else tree[i].count0=tree[i].max0=tree[i].left0=tree[i].right0=1;
return;
}
make(l,tree[i].mid,i<<1);
make(tree[i].mid,r,i<<1|1);
updata(i);
}
void oper(int a,int b,int i,int op)
{
down(i);
if(tree[i].l==a&&tree[i].r == b)
{
switch(op)
{
case 0:tree[i].fill0=1;break;
case 1:tree[i].fill1=1;break;
case 2:tree[i].chg^=1;break;
}
down(i);
return ;
}
if(b <= tree[i].mid )
oper(a,b,i<<1,op);
else if(a>=tree[i].mid)
oper(a,b,i<<1|1,op);
else
{
oper(a,tree[i].mid,i<<1,op);
oper(tree[i].mid,b,i<<1|1,op);
}
down(i<<1);
down(i<<1|1);
updata(i);
}
int ones(int a,int b,int i)
{
down(i);
if(a == tree[i].l&& b == tree[i].r)
return tree[i].count1;
if(b<=tree[i].mid)
return ones(a,b,i<<1);
else if(a>=tree[i].mid)
return ones(a,b,i<<1|1);
else return ones(a,tree[i].mid,i<<1)+ones(tree[i].mid,b,i<<1|1);
}
int ConOne(int a,int b,int i)//求连续1的个数
{
down(i);
if(a == tree[i].l && b == tree[i].r)
return tree[i].max1;
if(b <= tree[i].mid)
return ConOne(a,b,2*i);
else if(a >= tree[i].mid)
return ConOne(a,b,2*i+1);
else
{
int m1,m2,res;
m1 = ConOne(a,tree[i].mid,2*i);
m2 = ConOne(tree[i].mid,b,2*i+1);
res = min(tree[2*i].right1,tree[i].mid-a)+min(tree[2*i+1].left1,b-tree[i].mid);//注意这里
return max(res,max(m1,m2));
}
}
int main()
{
int Case;
scanf("%d",&Case);
while(Case--)
{
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
scanf("%d",&pa[i]);
make(0,n,1);
int a,b,op;
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&op,&a,&b);
if(op <= 2)
oper(a,b+1,1,op);
else if(op==3)
{
printf("%d/n",ones(a,b+1,1));
}
else printf("%d/n",ConOne(a,b+1,1));
}
}
}