线段树 HDU 3397(真)

时间:2023-03-09 04:23:47
线段树 HDU 3397(真)

5 种操作  0 1 然后 异或 似乎这种2个更新的先后每次都搞不清

覆盖有覆盖就可以不异或

也不知道为什么

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std; #define MAXN 100010 struct node
{
int l,r,ls,rs,ms; // 左边连续的1 右边 最多
int lz,rz,mz; // 0
int XOR,cov; // 异或 lazy
int sum; //和
}x[MAXN<<];
int z[MAXN];
void makexor(int a)//0 1 交换
{
swap(x[a].ls,x[a].lz);
swap(x[a].rs,x[a].rz);
swap(x[a].ms,x[a].mz);
x[a].sum=x[a].r-x[a].l+-x[a].sum;
}
void push_up(int a)
{
int len=x[a].r-x[a].l+;
x[a].ls=x[a<<].ls;
x[a].rs=x[a<<|].rs;
x[a].ms=max(x[a<<].ms,x[a<<|].ms);
if(x[a].ls==(len+)>>) //这边就是普通的区间合并
x[a].ls+=x[a<<|].ls;
if(x[a].rs==len>>)
x[a].rs+=x[a<<].rs;
int mid=(x[a].r+x[a].l)>>;
// if(z[mid]==z[mid+1]&&z[mid]==1) //一开始这里一直错 其实后面更新了 不用考虑这个
x[a].ms=max(x[a].ms,x[a<<].rs+x[a<<|].ls); x[a].lz=x[a<<].lz;
x[a].rz=x[a<<|].rz;
x[a].mz=max(x[a<<].mz,x[a<<|].mz);
if(x[a].lz==(len+)>>)
x[a].lz+=x[a<<|].lz;
if(x[a].rz==len>>)
x[a].rz+=x[a<<].rz;
x[a].mz=max(x[a].mz,x[a<<].rz+x[a<<|].lz); x[a].sum=x[a<<].sum+x[a<<|].sum;
}
void push_down(int a)
{
if(x[a].cov!=-)
{
int l=x[a].l;
int r=x[a].r;
int len=r-l+;
x[a<<].cov=x[a<<|].cov=x[a].cov;
x[a<<].XOR=x[a<<|].XOR=; x[a<<].ls=x[a<<].rs=x[a<<].ms=x[a].cov?(len+)>>:;
x[a<<].lz=x[a<<].rz=x[a<<].mz=x[a].cov?:(len+)>>;
x[a<<].sum=x[a].cov?(len+)>>:; x[a<<|].ls=x[a<<|].rs=x[a<<|].ms=x[a].cov?len>>:;
x[a<<|].lz=x[a<<|].rz=x[a<<|].mz=x[a].cov?:len>>;
x[a<<|].sum=x[a].cov?len>>:; x[a].cov=-;
}
if(x[a].XOR)
{
x[a].XOR=;
x[a<<].XOR^=;
x[a<<|].XOR^=;
makexor(a<<);
makexor(a<<|);
}
} void Build(int l,int r,int a)
{
x[a].l=l;
x[a].r=r;
x[a].XOR=;
x[a].cov=-;
if(l==r)
{
x[a].ls=x[a].rs=x[a].ms=(z[l]==);
x[a].lz=x[a].rz=x[a].mz=(z[l]==);
x[a].sum=z[l];
x[a].cov=z[l];
return ;
}
int mid=(l+r)>>;
Build(l,mid,a<<);
Build(mid+,r,a<<|);
push_up(a);
}
void update(int l,int r,int a1,int b1,int w,int a)
{
push_down(a);
if(a1<=l&&r<=b1)
{
if(w<)
{
int len=r-l+;
x[a].cov=w;
x[a].ls=x[a].rs=x[a].ms=w?len:;
x[a].lz=x[a].rz=x[a].mz=w?:len;
x[a].sum=w?len:;
x[a].XOR=;
}
else
{
x[a].XOR=;
makexor(a);
}
return ;
}
int mid=(l+r)>>;
if(a1<=mid)
update(l,mid,a1,b1,w,a<<);
if(b1>mid)
update(mid+,r,a1,b1,w,a<<|);
push_up(a);
}
int query_sum(int L,int R,int l,int r,int rt)
{
if(L<=l&&r<=R) {
return x[rt].sum;
}
push_down(rt);
int m=(l+r)>>;
int ans=;
if(L<=m)
ans+=query_sum(L,R,l,m,rt<<);
if(m<R)
ans+=query_sum(L,R,m+,r,rt<<|);
return ans;
}
int query_len(int L,int R,int l,int r,int rt)
{
push_down(rt);
if(L<=l&&r<=R) {
return x[rt].ms;
} int m=(l+r)>>;
int ans=;
if(L<=m)
ans=max(ans,query_len(L,R,l,m,rt<<));
if(m<R)
ans=max(ans,query_len(L,R,m+,r,rt<<|));
return max(ans,min(m-L+,x[rt<<].rs)+min(R-m,x[rt<<|].ls));
} int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
scanf("%d",&z[i]);
Build(,n,); while(m--)
{
int op,a,b;
scanf("%d%d%d",&op,&a,&b);
a++;
b++;
if(op<=)
update(,n,a,b,op,);
else if(op==)
printf("%d\n",query_sum(a,b,,n,));
else
printf("%d\n",query_len(a,b,,n,));
}
}
return ;
}