只过了hack,玄关求调
查看原帖
只过了hack,玄关求调
524091
dami826楼主2024/8/7 16:31
#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; 
}
2024/8/7 16:31
加载中...