线段树求调
查看原帖
线段树求调
767295
hfjqwq楼主2024/8/12 19:02

rt

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define mid ((l+r)>>1)
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
const int N=1e5+10;
int n,m,a[N];
struct Node{
	int il,ir,ln,rn,mx,len,sum,lzy_change,lzy_huo;
}tr[N<<2];
void setup(int p,int x){
	if(x==1) tr[p].il=tr[p].ir=tr[p].mx=tr[p].ln=tr[p].rn=tr[p].sum=1;
	tr[p].len=1;
}
void pushup(Node p,const Node &lp,const Node &rp){
	if(lp.rn==rp.ln&&lp.rn==1) p.mx=max({lp.ir+rp.il,lp.mx,rp.mx});
	else p.mx=max(lp.mx,rp.mx);
	p.ln=lp.ln; p.rn=rp.rn;
	p.len=lp.len+rp.len;
	if(lp.rn==rp.ln&&lp.rn==1&&lp.mx==lp.len) p.il=lp.len+rp.il;
	else p.il=lp.il;
	if(lp.rn==rp.ln&&lp.rn==1&&rp.mx==rp.len) p.ir=rp.len+lp.ir;
	else p.ir=rp.ir;
	p.sum=lp.sum+rp.sum;
}
void build(int p,int l,int r){
	tr[p].lzy_change=-1;
	if(l==r){
		setup(p,a[l]);
		return;
	}
	build(ls(p),l,mid);
	build(rs(p),mid+1,r);
	pushup(tr[p],tr[ls(p)],tr[rs(p)]);
}
void maketag1(int p,int l,int r,int x){ // 异或懒标记
	if(x){
		tr[p].sum=r-l+1-tr[p].sum;
		tr[p].lzy_huo^=x;
	}
}
void maketag2(int p,int l,int r,int x){ // 修改懒标记
	if(x!=-1){
		tr[p].sum=(r-l+1)*x;
		tr[p].lzy_huo=0;
		tr[p].lzy_change=x;
	}
}
void pushdown(int p,int l,int r){
	if(!tr[p].lzy_huo&&tr[p].lzy_change==-1) return;
	maketag2(p,l,r,tr[p].lzy_change);
	maketag1(p,l,r,tr[p].lzy_huo);
	tr[p].lzy_huo=0; tr[p].lzy_change=-1;
}
void update(int p,int l,int r,int L,int R,int opt){
	if(l>=L&&r<=R){
		if(opt==1) maketag2(p,l,r,0);
		else if(opt==2) maketag2(p,l,r,1);
		else maketag1(p,l,r,1);
	}
	pushdown(p,l,r);
	if(L<=mid) update(ls(p),l,mid,L,R,opt);
	if(R>mid) update(rs(p),mid+1,r,L,R,opt);
	pushup(tr[p],tr[ls(p)],tr[rs(p)]);
}
Node query(int p,int l,int r,int L,int R){
	if(l>R||r<L) return (Node){0,0,0,0,0,0,0,-1,0}; 
	if(l>=L&&r<=R) return tr[p];
	Node pp,lp=query(ls(p),l,mid,L,R),rp=query(rs(p),mid+1,r,L,R);
	pushup(pp,lp,rp);
	return pp;
}
signed main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>a[i];
	build(1,1,n);
	while(m--){
		int opt,l,r;
		cin>>opt>>l>>r;
		if(!opt)
			update(1,1,n,l,r,1);
		else if(opt==1)
			update(1,1,n,l,r,2);	
		else if(opt==2)
			update(1,1,n,l,r,3);
		else if(opt==3)
			cout<<query(1,1,n,l,r).sum<<'\n';
		else
			cout<<query(1,1,n,l,r).mx<<'\n';
	}
	return 0;
}
2024/8/12 19:02
加载中...