C++线段树模板
  • 板块学术版
  • 楼主smby_mobei
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/12/19 10:56
  • 上次更新2024/12/19 10:56:53
查看原帖
C++线段树模板
1437401
smby_mobei楼主2024/12/19 10:56

呃呃呃,写了好久写的,呜呜呜┭┮﹏┭┮

求大佬指正

struct segtree{
	int q,m,n;
	vector<int> mx,mn,lz,lzm,sum;
	const vector<int>&a;
	segtree(int sz,const vector<int>&_a):a(_a){
		mx.assign(sz<<2,0);
		mn.assign(sz<<2,0);
		lz.assign(sz<<2,0);
		lzm.assign(sz<<2,0);
		sum.assign(sz<<2,0);
		n=sz;
		build(1,1,sz);
	}
	void pushup(int x){
		sum[x]=sum[x<<1]+sum[(x<<1)+1];
		mx[x]=max(mx[x<<1],mx[(x<<1)+1]);
		mn[x]=min(mn[x<<1],mn[(x<<1)+1]);
	}
	void pushdown(int x,int l,int r){
		int mid=(l+r)>>1;
		sum[x<<1]=sum[x<<1]*lzm[x]+lz[x]*(mid-l+1),sum[(x<<1)+1]=sum[(x<<1)+1]*lzm[x]+lz[x]*(r-mid);
		mx[x<<1]=mx[x<<1]*lzm[x]+lz[x],mx[(x<<1)+1]=mx[(x<<1)+1]*lzm[x]+lz[x];
		mn[x<<1]=mn[x<<1]*lzm[x]+lz[x],mn[(x<<1)+1]=mn[(x<<1)+1]*lzm[x]+lz[x];
		if(mn[x<<1]>mx[x<<1])swap(mn[x<<1],mn[x<<1]);
		if(mn[x<<1|1]>mx[x<<1|1])swap(mn[x<<1|1],mn[x<<1|1]);
		lz[x<<1]=lz[x<<1]*lzm[x]+lz[x],lz[(x<<1)+1]=lz[(x<<1)+1]*lzm[x]+lz[x];
		lzm[x<<1]*=lzm[x],lzm[(x<<1)+1]*=lzm[x];
		lz[x]=0;
		lzm[x]=1;
	}
	void build(int x,int l,int r){
		lzm[x]=1;
		if(l==r){
			sum[x]=a[l];
			mn[x]=a[l];
			mx[x]=a[l];
			return;	
		}
		int mid=(l+r)>>1;
		build(x<<1,l,mid);
		build((x<<1)+1,mid+1,r);
		pushup(x);
	}
	int qsum(int tl,int tr){return qsum(1,tl,tr,1,n);}
	int qsum(int x,int tl,int tr,int l,int r){
		if(tl<=l&&r<=tr)return sum[x];
		int mid=(l+r)>>1,res=0;
		pushdown(x,l,r);
		if(tr>mid)res+=qsum((x<<1)+1,tl,tr,mid+1,r);
		if(tl<=mid)res+=qsum(x<<1,tl,tr,l,mid);
		return res;
	}
	int qmax(int tl,int tr){return qmax(1,tl,tr,1,n);}   
	int qmax(int x,int tl,int tr,int l,int r){
		if(tl<=l&&r<=tr)return mx[x];
		int mid=l+r>>1,res=-0x3f3f3f3f3f3f3f3f;
		pushdown(x,l,r);
		if(tr>mid)res=max(res,qmax((x<<1)+1,tl,tr,mid+1,r));
		if(tl<=mid)res=max(res,qmax(x<<1,tl,tr,l,mid));
		return res;
	}
	int qmin(int tl,int tr){return qmin(1,tl,tr,1,n);} 
	int qmin(int x,int tl,int tr,int l,int r){
		if(tl<=l&&r<=tr)return mn[x];
		int mid=l+r>>1,res=0x3f3f3f3f3f3f3f3f;
		pushdown(x,l,r);
		if(tr>mid)res=min(res,qmin((x<<1)+1,tl,tr,mid+1,r));
		if(tl<=mid)res=min(res,qmin(x<<1,tl,tr,l,mid));
		return res;
	}
	void add(int t,int pl){add(1,t,t,1,n,pl);}
	void add(int tl,int tr,int pl){add(1,tl,tr,1,n,pl);}                                                                       
	void add(int x,int tl,int tr,int l,int r,int pl){
		if(tl<=l&&r<=tr){
			lz[x]+=pl;
			sum[x]+=(r-l+1)*pl;
			mx[x]+=pl;
			mn[x]+=pl;
			return;
		}
		int mid=(l+r)>>1;
		pushdown(x,l,r);
		if(tr>mid)add((x<<1)+1,tl,tr,mid+1,r,pl);
		if(tl<=mid)add(x<<1,tl,tr,l,mid,pl);
		pushup(x);
		return;
	}
	void times(int t,int tm){times(1,t,t,1,n,tm);}  
	void times(int tl,int tr,int tm){times(1,tl,tr,1,n,tm);}                                                                       
	void times(int x,int tl,int tr,int l,int r,int tm){
		if(tl<=l&&r<=tr){
			lzm[x]*=tm;
			lz[x]*=tm;
			sum[x]*=tm;
			mx[x]*=tm;
			mn[x]*=tm;
			if(tm<0)swap(mx[x],mn[x]);
			return;
		}
		int mid=(l+r)>>1;
		pushdown(x,l,r);
		if(tr>mid)times((x<<1)+1,tl,tr,mid+1,r,tm);
		if(tl<=mid)times(x<<1,tl,tr,l,mid,tm);
		pushup(x);
		return;
	}
};
2024/12/19 10:56
加载中...