EastIsRed @ 2023-12-06 17:15:23
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,a[100086];
struct node{
int l,r;
struct message{
int sum,l_len,r_len,m_len;
message():sum(0),l_len(0),r_len(0),m_len(0){}
message(int _sum,int _l_len,int _r_len,int _m_len):sum(_sum),l_len(_l_len),r_len(_r_len),m_len(_m_len){}
message(const message& rhs):sum(rhs.sum),l_len(rhs.l_len),r_len(rhs.r_len),m_len(rhs.m_len){}
void set(int val=0)
{
sum=l_len=r_len=m_len=val;
}
}mess[2];
int lzd1,lzd2;
}tr[400086];
inline node::message merge_mess(const node::message& a,const node::message& b,int lenl,int lenr)
{
return node::message(a.sum+b.sum,a.l_len==lenl?lenl+b.l_len:a.l_len,b.r_len==lenr?a.r_len+lenr:b.r_len,max({a.m_len,b.m_len,a.r_len+b.l_len}));
}
inline void push_up(int now)
{
int mid=tr[now].l+tr[now].r>>1;
tr[now].mess[0]=merge_mess(tr[now<<1].mess[0],tr[now<<1|1].mess[0],mid-tr[now].l+1,tr[now].r-mid);
tr[now].mess[1]=merge_mess(tr[now<<1].mess[1],tr[now<<1|1].mess[1],mid-tr[now].l+1,tr[now].r-mid);
}
void build(int now,int l,int r)
{
tr[now].l=l;
tr[now].r=r;
tr[now].lzd1=-1;
tr[now].lzd2=0;
if(l!=r)
{
int mid=l+r>>1;
build(now<<1,l,mid);
build(now<<1|1,mid+1,r);
push_up(now);
}
else tr[now].mess[a[l]].set(1),tr[now].mess[a[l]^1].set();
}
inline void lzd_down(int now)
{
if(tr[now].lzd1!=-1)
{
tr[now<<1].mess[tr[now].lzd1].set(tr[now<<1].r-tr[now<<1].l+1);
tr[now<<1].mess[tr[now].lzd1^1].set();
tr[now<<1|1].mess[tr[now].lzd1].set(tr[now<<1|1].r-tr[now<<1|1].l+1);
tr[now<<1|1].mess[tr[now].lzd1^1].set();
tr[now<<1].lzd1=tr[now<<1|1].lzd1=tr[now].lzd1;
tr[now<<1].lzd2=tr[now<<1|1].lzd2=0;
tr[now].lzd1=-1;
}
if(tr[now].lzd2)
{
swap(tr[now<<1].mess[0],tr[now<<1].mess[1]);
swap(tr[now<<1|1].mess[0],tr[now<<1|1].mess[1]);
tr[now].lzd2=0;
if(tr[now<<1].lzd1!=-1)
tr[now<<1].lzd1^=1;
else tr[now<<1].lzd2^=1;
if(tr[now<<1|1].lzd1!=-1)
tr[now<<1|1].lzd1^=1;
else tr[now<<1|1].lzd2^=1;
}
}
void change(int now,int l,int r,int val)
{
if(l<=tr[now].l&&tr[now].r<=r)
{
tr[now].mess[val].set(tr[now].r-tr[now].l+1);
tr[now].mess[val^1].set();
tr[now].lzd1=val;
tr[now].lzd2=0;
return;
}
int mid=tr[now].l+tr[now].r>>1;
lzd_down(now);
if(l<=mid)
change(now<<1,l,r,val);
if(mid<r)
change(now<<1|1,l,r,val);
push_up(now);
}
void reverse(int now,int l,int r)
{
if(l<=tr[now].l&&tr[now].r<=r)
{
swap(tr[now].mess[0],tr[now].mess[1]);
if(tr[now].lzd1!=-1)
tr[now].lzd1^=1;
else tr[now].lzd2^=1;
return;
}
int mid=tr[now].l+tr[now].r>>1;
lzd_down(now);
if(l<=mid)
reverse(now<<1,l,r);
if(mid<r)
reverse(now<<1|1,l,r);
push_up(now);
}
int query_sum(int now,int l,int r)
{
if(l<=tr[now].l&&tr[now].r<=r)
return tr[now].mess[1].sum;
int mid=tr[now].l+tr[now].r>>1,sum=0;
lzd_down(now);
if(l<=mid)
sum+=query_sum(now<<1,l,r);
if(mid<r)
sum+=query_sum(now<<1|1,l,r);
return sum;
}
node::message query_mess1(int now,int l,int r)
{
if(l<=tr[now].l&&tr[now].r<=r)
return tr[now].mess[1];
int mid=tr[now].l+tr[now].r>>1;
lzd_down(now);
if(r<=mid)
return query_mess1(now<<1,l,r);
else if(l>mid)
return query_mess1(now<<1|1,l,r);
else return merge_mess(query_mess1(now<<1,l,r),query_mess1(now<<1|1,l,r),mid-max(l,tr[now].l)+1,min(r,tr[now].r)-mid);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
scanf("%d",a+i);
build(1,0,n-1);
while(m--)
{
int op,l,r;
scanf("%d%d%d",&op,&l,&r);
if(op<=1)
change(1,l,r,op);
else if(op==2)
reverse(1,l,r);
else if(op==3)
printf("%d\n",query_sum(1,l,r));
else printf("%d\n",query_mess1(1,l,r).m_len);
//node::message mess=query_mess1(1,l,r);
//printf("%d %d %d %d\n\n",mess.sum,mess.l_len,mess.r_len,mess.m_len);
}
return 0;
}
by what_else @ 2023-12-06 17:52:59
6,我看看