dami826 @ 2024-08-07 16:31:53
#include<bits/stdc++.h>
using namespace std;
int n,m,s[100001];
struct segment_tree{
int one[400001],len[400001][2],llen[400001][2],rlen[400001][2],cover[400001],reverse[400001],tmp[400001][3];//cover:0不须覆盖,1覆盖0,2覆盖1
void up(int left,int right,int index,int mid){
one[index]=one[index*2]+one[index*2+1];
// printf("one %d comes to %d 1\n",index,one[index]);
// printf("one %d(%d)+one %d(%d)=one %d\n",index*2,one[index*2],index*2+1,one[index*2+1],index);
for(int i=0;i<=1;i++){
len[index][i]=max(max(len[index*2][i],len[index*2+1][i]),rlen[index*2][i]+llen[index*2+1][i]);
llen[index][i]=(llen[index*2][i]==mid-left+1)?(llen[index*2][i]+llen[index*2+1][i]):(llen[index*2][i]);
rlen[index][i]=(rlen[index*2+1][i]==right-mid)?(rlen[index*2][i]+rlen[index*2+1][i]):(rlen[index*2+1][i]);
}
}
void build(int left,int right,int index){
if(left==right){
one[index]=s[left];
// printf("one %d comes to %d 2\n",index,one[index]);
len[index][s[left]]=llen[index][s[left]]=rlen[index][s[left]]=1;
return;
}
int mid=(left+right)/2;
build(left,mid,index*2);
build(mid+1,right,index*2+1);
up(left,right,index,mid);
}
void down(int left,int right,int index,int mid){
if(cover[index]){
cover[index*2]=cover[index*2+1]=cover[index];
reverse[index*2]=reverse[index*2+1]=0;
one[index*2]=(cover[index]-1)?(mid-left+1):0;
one[index*2+1]=(cover[index]-1)?(right-mid):0;
// printf("one %d comes to %d 3\n",index*2,one[index*2]);
// printf("one %d comes to %d 4\n",index*2+1,one[index*2+1]);
len[index*2][cover[index]^1]=llen[index*2][cover[index]-1]=rlen[index*2][cover[index-1]]=mid-left+1;
len[index*2][(cover[index]-1)^1]=llen[index*2][(cover[index]-1)^1]=rlen[index*2][(cover[index]-1)^1]=0;
len[index*2+1][cover[index]-1]=llen[index*2+1][cover[index]-1]=rlen[index*2+1][cover[index-1]]=right-mid;
len[index*2+1][(cover[index]-1)^1]=llen[index*2+1][(cover[index]-1)^1]=rlen[index*2+1][(cover[index]-1)^1]=0;
reverse[index]=cover[index]=0;
}
if(reverse[index]){
one[index*2]=(mid-left+1)-one[index*2];
one[index*2+1]=(right-mid)-one[index*2+1];
// printf("one %d comes to %d 5\n",index*2,one[index*2]);
// printf("one %d comes to %d 6\n",index*2+1,one[index*2+1]);
if(cover[index*2]){
(cover[index*2]-1)?cover[index*2]--:cover[index*2]++;
}
else{
reverse[index*2]^=1;
}
if(cover[index*2+1]){
(cover[index*2+1]-1)?cover[index*2+1]--:cover[index*2+1]++;
}
else{
reverse[index*2+1]^=1;
}
swap(len[index][0],len[index][1]);
swap(llen[index][0],llen[index][1]);
swap(rlen[index][0],rlen[index][1]);
reverse[index]=0;
}
}
void c_update(int gleft,int gright,int x,int left,int right,int index){//cover_update
//printf("c %d %d %d %d %d %d\n",gleft,gright,x,left,right,index);
if(right<gleft||gright<left){
return;
}
if(gleft<=left&&right<=gright){
cover[index]=x+1;
one[index]=x?(right-left+1):0;
// printf("one %d comes to %d 7\n",index,one[index]);
len[index][x]=llen[index][x]=rlen[index][x]=right-left+1;
len[index][x^1]=llen[index][x^1]=rlen[index][x^1]=0;
return;
}
int mid=(left+right)/2;
down(left,right,index,mid);
c_update(gleft,gright,x,left,mid,index*2);
c_update(gleft,gright,x,mid+1,right,index*2+1);
up(left,right,index,mid);
}
void r_update(int gleft,int gright,int left,int right,int index){
// printf("r %d %d %d %d %d\n",gleft,gright,left,right,index);
if(right<gleft||gright<left){
return;
}
if(gleft<=left&&right<=gright){
if(cover[index]){
(cover[index]-1)?cover[index]--:cover[index]++;
}
else{
reverse[index]^=1;
}
one[index]=(right-left+1)-one[index];
// printf("one %d comes to %d 8\n",index,one[index]);
swap(len[index][0],len[index][1]);
swap(llen[index][0],llen[index][1]);
swap(rlen[index][0],rlen[index][1]);
return;
}
int mid=(left+right)/2;
down(left,right,index,mid);
r_update(gleft,gright,left,mid,index*2);
r_update(gleft,gright,mid+1,right,index*2+1);
up(left,right,index,mid);
}
int one_search(int gleft,int gright,int left,int right,int index){
// printf("%d %d %d %d %d\n",gleft,gright,left,right,index);
if(right<gleft||gright<left){
// printf("Nope\n");
return 0;
}
if(gleft<=left&&right<=gright){
// printf("OK return %d\n",one[index]);
return one[index];
}
// printf("continue\n");
int mid=(left+right)/2;
down(left,right,index,mid);
return one_search(gleft,gright,left,mid,index*2)+one_search(gleft,gright,mid+1,right,index*2+1);
}
int* len_search(int gleft,int gright,int left,int right,int index){
// printf("%d %d %d %d %d\n",gleft,gright,left,right,index);
if(right<gleft||gright<left){
// printf("Nope\n");
tmp[index][0]=tmp[index][1]=tmp[index][2]=0;
return &tmp[index][0];
}
if(gleft<=left&&right<=gright){
tmp[index][0]=len[index][1];
tmp[index][1]=llen[index][1];
tmp[index][2]=rlen[index][1];
// printf("OK return %d %d\n",tmp[0],&tmp[0]);
return &tmp[index][0];
}
// printf("continue\n");
int mid=(left+right)/2;
down(left,right,index,mid);
int *a=len_search(gleft,gright,left,mid,index*2),*b=len_search(gleft,gright,mid+1,right,index*2+1);
tmp[index][1]=(*(a+1)==mid-left+1)?(*(a+1)+*(b+1)):*(a+1);
tmp[index][2]=(*(b+2)==right-mid)?(*(b+2)+*(a+2)):*(b+2);
tmp[index][0]=max(max(*a,*b),*(a+2)+*(b+1));
// printf("%d\n",*a);
return &tmp[index][0];
}
};
segment_tree tr;
int main(){
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&s[i]);
}
tr.build(1,n,1);
while(m--){
int op,l,r;
scanf("%d %d %d",&op,&l,&r);
l++;
r++;
switch(op){
case 0:case 1:tr.c_update(l,r,op,1,n,1);break;
case 2:tr.r_update(l,r,1,n,1);break;
case 3:printf("%d\n",tr.one_search(l,r,1,n,1));break;
case 4:
int *x=tr.len_search(l,r,1,n,1);
printf("%d\n",*x);
}
}
return 0;
}
by dami826 @ 2024-08-08 10:19:57
将down
函数中的swap
由
swap(len[index][0],len[index][1]);
swap(llen[index][0],llen[index][1]);
swap(rlen[index][0],rlen[index][1]);
换成
swap(len[index*2][0],len[index*2][1]);
swap(llen[index*2][0],llen[index*2][1]);
swap(rlen[index*2][0],rlen[index*2][1]);
swap(len[index*2+1][0],len[index*2+1][1]);
swap(llen[index*2+1][0],llen[index*2+1][1]);
swap(rlen[index*2+1][0],rlen[index*2+1][1]);
之后已AC,此贴结
by Night_early @ 2024-08-08 10:24:58
@dami826 问一下为什么
by dami826 @ 2024-08-08 10:31:56
@Night_early pushdown更新的应该是子节点的信息,父节点的信息在标懒标记的时候已经更新过了 我也不知道为什么这么离谱的错误居然能过样例和#11
by Night_early @ 2024-08-08 10:58:59
@dami826 确实,您有兴趣调我的吗https://www.luogu.com.cn/record/171322560