绝顶我为峰 @ 2019-10-06 16:42:50
救救我吧,这题太难调了。。。
#include<iostream>
#include<cstdio>
using namespace std;
#define int long long
int n,m,a[100001],ans[100001<<3],tag[100001<<3],rev[100001<<3],maxn[100001<<3][2],lmax[100001<<3][2],rmax[100001<<3][2],len[100001<<3];
inline int ls(int k)
{
return k<<1;
}
inline int rs(int k)
{
return k<<1|1;
}
inline void push_up(int k)
{
len[k]=len[ls(k)]+len[rs(k)];
ans[k]=ans[ls(k)]+ans[rs(k)];
maxn[k][0]=max(max(maxn[ls(k)][0],maxn[rs(k)][0]),rmax[ls(k)][0]+lmax[rs(k)][0]);
maxn[k][1]=max(max(maxn[ls(k)][1],maxn[rs(k)][1]),rmax[ls(k)][1]+lmax[rs(k)][1]);
lmax[k][0]=lmax[ls(k)][0];
lmax[k][1]=lmax[ls(k)][1];
if(!ans[ls(k)])
lmax[k][0]+=lmax[rs(k)][0];
if(ans[ls(k)]==len[ls(k)])
lmax[k][1]+=lmax[rs(k)][1];
rmax[k][0]=rmax[rs(k)][0];
rmax[k][1]=rmax[rs(k)][1];
if(!ans[rs(k)])
rmax[k][0]+=rmax[ls(k)][0];
if(ans[rs(k)]==len[rs(k)])
rmax[k][1]+=rmax[ls(k)][1];
}
inline void f(int k,int l,int r,int p1,int p2)
{
if(p1!=-1)
{
p2=0;
ans[k]=(r-l+1)*p1;
tag[k]=p1;
rev[k]=0;
maxn[k][p1]=lmax[k][p1]=rmax[k][p1]=r-l+1;
maxn[k][p1^1]=lmax[k][p1^1]=rmax[k][p1^1]=0;
}
if(p2)
{
ans[k]=r-l+1-ans[k];
if(tag[k]!=-1)
tag[k]^=1;
else
rev[k]^=1;
maxn[k][0]^=maxn[k][1]^=maxn[k][0]^=maxn[k][1];
lmax[k][0]^=lmax[k][1]^=lmax[k][0]^=lmax[k][1];
rmax[k][0]^=rmax[k][1]^=rmax[k][0]^=rmax[k][1];
}
}
inline void push_down(int k,int l,int r)
{
int mid=(l+r)>>1;
f(ls(k),l,mid,tag[k],rev[k]);
f(rs(k),mid+1,r,tag[k],rev[k]);
tag[k]=-1;
rev[k]=0;
}
void build(int k,int l,int r)
{
if(l==r)
{
ans[k]=a[l];
len[k]=1;
tag[k]=-1;
maxn[k][a[l]]=1;
lmax[k][a[l]]=1;
rmax[k][a[l]]=1;
return;
}
tag[k]=-1;
int mid=(l+r)>>1;
build(ls(k),l,mid);
build(rs(k),mid+1,r);
push_up(k);
}
void update(int nl,int nr,int l,int r,int k,int p)
{
if(l>=nl&&r<=nr)
{
if(p==0||p==1)
{
tag[k]=p;
ans[k]=(r-l+1)*p;
maxn[k][p]=lmax[k][p]=rmax[k][p]=r-l+1;
maxn[k][p^1]=lmax[k][p^1]=rmax[l][p^1]=0;
}
else
{
ans[k]=r-l+1-ans[k];
rev[k]^=1;
maxn[k][0]^=maxn[k][1]^=maxn[k][0]^=maxn[k][1];
lmax[k][0]^=lmax[k][1]^=lmax[k][0]^=lmax[k][1];
rmax[k][0]^=rmax[k][1]^=rmax[k][0]^=rmax[k][1];
}
return;
}
push_down(k,l,r);
int mid=(l+r)>>1;
if(nl<=mid)
update(nl,nr,l,mid,ls(k),p);
if(nr>mid)
update(nl,nr,mid+1,r,rs(k),p);
push_up(k);
}
int query1(int nl,int nr,int l,int r,int k)
{
if(l>=nl&&r<=nr)
return ans[k];
push_down(k,l,r);
int mid=(l+r)>>1,res=0;
if(nl<=mid)
res+=query1(nl,nr,l,mid,ls(k));
if(nr>mid)
res+=query1(nl,nr,mid+1,r,rs(k));
return res;
}
int query2(int nl,int nr,int l,int r,int k)
{
if(l>=nl&&r<=nr)
return maxn[k][1];
push_down(k,l,r);
int mid=(l+r)>>1,res=0;
if(nl<=mid)
res=max(res,query2(nl,nr,l,mid,ls(k)));
if(nr>mid)
res=max(res,query2(nl,nr,mid+1,r,rs(k)));
res=max(res,rmax[ls(k)][1]+lmax[rs(k)][1]);
return res;
}
signed main()
{
scanf("%lld%lld",&n,&m);
for(register int i=1;i<=n;++i)
scanf("%lld",&a[i]);
build(1,1,n);
while(m--)
{
int opt,x,y;
scanf("%lld%lld%lld",&opt,&x,&y);
++x,++y;
if(opt==0)
update(x,y,1,n,1,0);
if(opt==1)
update(x,y,1,n,1,1);
if(opt==2)
update(x,y,1,n,1,2);
if(opt==3)
printf("%lld\n",query1(x,y,1,n,1));
if(opt==4)
printf("%lld\n",query2(x,y,1,n,1));
}
return 0;
}
by _gifbmp @ 2019-10-06 16:48:16
@绝顶我为峰 query应该返回一个结构体,不然正确性没法保证
by 绝顶我为峰 @ 2019-10-06 16:48:51
@_gifbmp 结构体也是10分。。。
by _gifbmp @ 2019-10-06 16:50:08
@绝顶我为峰 那可能是其他什么地方错了,我看看
by 绝顶我为峰 @ 2019-10-06 16:50:31
@_gifbmp 谢谢大佬
by _gifbmp @ 2019-10-06 16:50:59
@绝顶我为峰 这题合并没有这么复杂吧……
by 绝顶我为峰 @ 2019-10-06 16:51:15
@_gifbmp 蛤?
by _gifbmp @ 2019-10-06 16:52:56
@绝顶我为峰 不过你维护的信息是对的
by 绝顶我为峰 @ 2019-10-06 16:53:49
@_gifbmp 那是哪里错了...
by _gifbmp @ 2019-10-06 17:04:59
@绝顶我为峰 为什么窝觉得您
maxn[k][0]^=maxn[k][1]^=maxn[k][0]^=maxn[k][1];
lmax[k][0]^=lmax[k][1]^=lmax[k][0]^=lmax[k][1];
rmax[k][0]^=rmax[k][1]^=rmax[k][0]^=rmax[k][1];
这几句话有问题,能不能套个括号
by 绝顶我为峰 @ 2019-10-06 17:06:18
@_gifbmp QAQ不是这里QAQ