线段树求条,悬 2 关
查看原帖
线段树求条,悬 2 关
995753
__Octhyccc__楼主2024/8/24 17:24
#include<bits/stdc++.h>
#define int long long
using namespace std;
constexpr int MAXN=2e5+10;
constexpr int MAXTREE=8e5+10;
int n,f,op,l,r,k;
struct Tree{//支持区间加的线段树 
	int pl[MAXTREE],tree[MAXTREE],val[MAXN];
	int sum[MAXTREE];
	void Init(){
		memset(pl,0,sizeof(pl));
		memset(tree,0,sizeof(tree));
		memset(val,0,sizeof(val));
		memset(sum,0,sizeof(sum));
	}
	void Build(int l,int r,int i){
		if(l==r){
			sum[i]=val[l];
			return;
		}
		int mid=(l+r)>>1;
		Build(l,mid,i<<1);
		Build(mid+1,r,i<<1|1);
		sum[i]=sum[i<<1]+sum[i<<1|1];
		return;
	}
	void Push(int i,int l,int r){
		int mid=(l+r)>>1;
		int L=i<<1,R=i<<1|1;
		pl[L]+=pl[i],pl[R]+=pl[i];
		sum[L]+=pl[i]*(mid-l+1);
		sum[R]+=pl[i]*(r-mid);
		pl[i]=0;
		return;
	}
	void Add(int l,int r,int k,int nl,int nr,int i){//加的总范围 [l,r],单点要加的值 k,现在的区间 [nl,nr],线段树数组第 i 个 
		if(l<=nl && r>=nr){
			pl[i]+=k;
			sum[i]=(nr-nl+1)*k;
			return;
		}
		Push(i,nl,nr);
		int mid=(nl+nr)>>1;
		if(mid>=l)Add(l,r,k,l,mid,i<<1);
		if(mid<=r)Add(l,r,k,mid+1,r,i<<1|1);
		sum[i]=sum[i<<1]+sum[i<<1|1];
		return;
	}
	int Query(int ql,int qr,int nl,int nr,int i){//询问和总范围 [ql,qr],现在的区间 [nl,nr],线段树数组第 i 个,总和 S 
		int SS=0;
		if(ql>=nl && nr<=qr)SS+=sum[i];
		int mid=(nl+nr)>>1;
		if(mid>=ql)SS+=Query(ql,qr,nl,mid,i<<1);
		if(mid<=nr)SS+=Query(ql,qr,mid+1,nr,i<<1|1);
		return SS;
	}
}MyTree;
signed main(){
	scanf("%lld%lld",&n,&f);
	for(int i=1;i<=n;i++)scanf("%lld",&MyTree.val[i]);
	MyTree.Build(1,n,1);
	for(int i=0;i<f;i++){
		scanf("%lld",&op);
		if(op==1){
			scanf("%lld%lld%lld",&l,&r,&k);
			MyTree.Add(l,r,k,1,n,1);
		}
		else if(op==2){
			scanf("%lld",&k);
			MyTree.Add(1,1,k,1,n,1);
		}
		else if(op==3){
			scanf("%lld",&k);
			MyTree.Add(1,1,-k,1,n,1);
		}
		else if(op==4){
			scanf("%lld%lld",&l,&r);
			printf("%lld\n",MyTree.Query(l,r,1,n,1));
		}
		else{
			printf("%lld\n",MyTree.Query(1,1,1,n,1));
		}
	}
	return 0;
}

问题:RE

2024/8/24 17:24
加载中...