刚学的线段树求调RE
查看原帖
刚学的线段树求调RE
738882
OIer_dcy__AK_IOI楼主2024/1/5 12:53
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+10;
struct tree{ //树的结构体 
	int l,r,sum,add;
	/* l是当前节点覆盖区间的左端点
	   r是右前节点覆盖区间的右端点
	   sum是当前区间结点的和
	   add是懒标记 
	*/
}t[4*N]; //存树 
int n,q; //序列长度为n,查询次数q 
int a[N]; //a数组存序列 
//建树
inline void build(int pos,int l,int r){ //pos为当前节点下标,l为左端点,r为右端点 
	t[pos].l=l,t[pos].r=r; //当前节点的左端点为l,右端点为r 
	if(l==r){ //如果是叶子节点(区间长度为1) 
		t[pos].sum=a[l]; //当前区间的和为节点本身 
		return ;  //回溯 
	}else{
		int mid=(l+r)>>1; //取区间中点 
		int left=pos<<1; //左子树根节点的下标 
		int right=pos<<1|1; //右子树根节点的下标 
		build(left,1,mid); //递归遍历左子树(求左子树的最大值) 
		build(right,mid+1,r); //递归遍历右子树(求右子树的最大值) 
		t[pos].sum=t[left].sum+t[right].sum; //当前节点的最大值=左子树最大值+右子树最大值
	}
}
//向下继承(懒标记的向下更新) 
void pushdown(int pos){
	int left=pos<<1,right=pos<<1|1;
	auto &root=	t[pos],&ll=t[left],&rr=t[right];
	if(root.add!=0){
		ll.add+=root.add;
		ll.sum+=(ll.r-ll.l+1)*root.add;
		rr.add+=root.add;
		rr.sum+=(rr.r-rr.l+1)*root.add;
		root.add=0;
	}
}
//区间修改 
inline void update2(int pos,int x,int y,int k){
	int l=t[pos].l,r=t[pos].r,mid=(l+1)>>1;
	if(x<=l&&y>=r){
		t[pos].sum+=(r-l+1)*k;
		t[pos].add+=k; //懒标记,子节点还没有更新,在下次查询以及区间修改时更新 
	}else{
		pushdown(pos);
		int left=pos<<1,right=pos<<1|1;
		if(x<=mid){
			update2(left,x,y,k);
		}
		if(y>=mid){
			update2(right,x,y,k);
		}
		t[pos].sum=t[left].sum+t[right].sum;
	}
}
//查询区间最大值 
inline int getmax(int pos,int x,int y){
	int l=t[pos].l,r=t[pos].r,mid=(l+r)>>1;
	if(x<=l&&y>=r){
		return t[pos].sum;
	}
	pushdown(pos);
	int ans=0,left=pos*2,right=pos*2+1;
	if(x<=mid){
		ans+=getmax(left,x,y);
	}
	if(y>mid){
		ans+=getmax(right,x,y);
	}
	return ans;
}
signed main(){
	//输入 
	scanf("%lld%lld",&n,&q);
	for(int i=1;i<=n;i++){
		scanf("%lld",&a[i]);
	}
	build(1,1,n); //建树 
	while(q--){ //q次查询(修改) 
		int op;
		scanf("%lld",&op);
		if(op==1){ //区间修改  
			int x,y,d;
			scanf("%lld%lld%lld",&x,&y,&d);
			update2(1,x,y,d);
		}else if(op==2){ //区间查询 
			int x,y;
			scanf("%lld%lld",&x,&y);
			printf("%lld\n",getmax(1,x,y));
		}
	}
	return 0;
}
2024/1/5 12:53
加载中...