一直在用3397的现有代码去掉功能来代入这道题
但是莫名的TLE了。
于是按照网上大部分的方法,多维护了黑色的左,中,右最长连续
由于PushDown的时候忘记了把延迟标记传递下去,又贡献了几次WA
最后在输入加速和inline的帮助下,成功600ms AC
代码如下:
// 593ms
#include<iostream>
#include<cstdio>
using namespace std;
#define maxn 100010
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
struct Tree
{
int l,r;
int lazy;
int lsum,msum,rsum;//white
int lnum,mnum,rnum;//black
}tree[maxn<<2];
int num[maxn];
inline void PushUp(int rt)
{
tree[rt].lsum=tree[rt<<1].lsum;
tree[rt].rsum=tree[rt<<1|1].rsum;
if(tree[rt].lsum==(tree[rt<<1].r-tree[rt<<1].l+1))
tree[rt].lsum+=tree[rt<<1|1].lsum;
if(tree[rt].rsum==(tree[rt<<1|1].r-tree[rt<<1|1].l+1))
tree[rt].rsum+=tree[rt<<1].rsum;
tree[rt].msum=max(tree[rt<<1].rsum+tree[rt<<1|1].lsum,max(tree[rt<<1].msum,tree[rt<<1|1].msum));
tree[rt].lnum=tree[rt<<1].lnum;
tree[rt].rnum=tree[rt<<1|1].rnum;
if(tree[rt].lnum==(tree[rt<<1].r-tree[rt<<1].l+1))
tree[rt].lnum+=tree[rt<<1|1].lnum;
if(tree[rt].rnum==(tree[rt<<1|1].r-tree[rt<<1|1].l+1))
tree[rt].rnum+=tree[rt<<1].rnum;
tree[rt].mnum=max(tree[rt<<1].rnum+tree[rt<<1|1].lnum,max(tree[rt<<1].mnum,tree[rt<<1|1].mnum));
}
inline void PushDown(int rt)
{
if(tree[rt].lazy){
swap(tree[rt<<1].lsum,tree[rt<<1].lnum);
swap(tree[rt<<1].rsum,tree[rt<<1].rnum);
swap(tree[rt<<1].msum,tree[rt<<1].mnum);
swap(tree[rt<<1|1].lsum,tree[rt<<1|1].lnum);
swap(tree[rt<<1|1].rsum,tree[rt<<1|1].rnum);
swap(tree[rt<<1|1].msum,tree[rt<<1|1].mnum);
tree[rt<<1].lazy^=1;
tree[rt<<1|1].lazy^=1;
tree[rt].lazy^=1;
}
}
inline void build(int l,int r,int rt)
{
tree[rt].l=l;
tree[rt].r=r;
tree[rt].lazy=0;
if(l==r) {
if(num[l]){
tree[rt].lsum=tree[rt].rsum=tree[rt].msum=1;
tree[rt].lnum=tree[rt].rnum=tree[rt].mnum=0;
}
else{
tree[rt].lsum=tree[rt].rsum=tree[rt].msum=0;
tree[rt].lnum=tree[rt].rnum=tree[rt].mnum=1;
}
return ;
}
int m=(l+r)>>1;
build(lson);
build(rson);
PushUp(rt);
}
inline void update(int x,int y,int rt)
{
int l,r;
l=tree[rt].l;
r=tree[rt].r;
if(l==x&&r==y){
swap(tree[rt].lnum,tree[rt].lsum);
swap(tree[rt].rnum,tree[rt].rsum);
swap(tree[rt].mnum,tree[rt].msum);
tree[rt].lazy^=1;
return ;
}
PushDown(rt);
int m=(l+r)>>1;
if(x<=m) update(x,min(m,y),rt<<1);
if(y>m) update(max(m+1,x),y,rt<<1|1);
PushUp(rt);
}
inline int query(int x,int y,int rt)
{
int l,r;
l=tree[rt].l;
r=tree[rt].r;
if(l==x&&r==y){
return tree[rt].msum;
}
PushDown(rt);
int m=(l+r)>>1;
if(y<=m) return query(x,y,rt<<1);
else if(x>m) return query(x,y,rt<<1|1);
else{
int lr=query(x,m,rt<<1);
int rr=query(m+1,y,rt<<1|1);
return max(max(lr,rr),min(tree[rt<<1].rsum,tree[rt<<1].r-x+1)+min(tree[rt<<1|1].lsum,y-tree[rt<<1|1].l+1));
}
}
inline int input()
{
char c;
int ret=0;
c=getchar();
while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') ret=ret*10+c-'0',c=getchar();
return ret;
}
int main()
{
int n,m;
while(scanf("%d",&n)!=EOF){
for(int i=1;i<=n;i++)
num[i]=input();
m=input();
build(1,n,1);
while(m--){
int op,a,b;
op=input();a=input();b=input();
if(op==0)
printf("%d\n",query(a,b,1));
else
update(a,b,1);
}
}
return 0;
}