哪里错了 大佬看看
查看原帖
哪里错了 大佬看看
1206518
Nervegas楼主2024/4/7 20:52
#include<bits/stdc++.h>
#define maxn 100010
using namespace std;
typedef long long ll;
ll a[maxn],tree[maxn*4];
ll mark[maxn*4];
ll n,m;
void push_down(ll p,ll len){//标记下传 
	mark[p*2]+=mark[p];
	mark[p*2+1]+=mark[p];
	tree[p*2]+=mark[p]*(len-len/2);
	tree[p*2+1]+=mark[p]*(len/2);
	mark[p]=0; 
}
void build(ll l,ll r,ll p){//建树,先建左子树,后建右子树,p是当前点 
	if(l==r){
		tree[p]=a[l];
	}
	else{
		ll M=(l+r)/2;
		build(l,M,p*2);
		build(M,r,p*2+1);
		tree[p]=tree[p*2]+tree[p*2+1];
	}
}
void update(ll l,ll r,ll d,ll p,ll cl,ll cr){//l,r为要修改的区间,d为要加的数,cl,cr为当前区间 ,p为当前节点 
	if(cl>r||cr<l){//看是否有交集 无交集就return 
		return;
	} 
	else if(cl>=l&&cr<=r){//当前区间包含在目标区间 
		tree[p]+=(cr-cl+1)*d;//更新当前区间,记得乘以区间长度 
		if(cr>cl){//判断是否是叶子结点 如果是就不用 因为不会再向下传递标记 
			mark[p]+=d;//打标记 
		}
	} 
	else{//有交集但不是全部包含部分交叉 
		ll M=(cl+cr)/2;
		push_down(p, cr - cl + 1);//下放标记
        update(l,r,d,p*2,cl,M);
        update(l,r,d,p*2+1,M+1,cr);
        tree[p]=tree[p*2]+tree[p*2+1];//更新节点 
	}
}
ll query(ll l,ll r,ll p,ll cl,ll cr){
	if(cl>r||cr<l){
		return 0;
	} 
	else if(cl>=l&&cr<=r){
		return tree[p];
	}
	else{
		ll M=(cl+cr)/2;
		push_down(p,cr-cl+1);
		return query(l,r,p*2,cl,M)+query(l,r,p*2+1,M+1,cr);
	}
} 
int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	build(1,n,1);
    for(int i=1;i<=m;i++){
		int op,x,y,k;
		cin>>op;
		if(op==1){
			cin>>x>>y>>k;
			update(x,y,k,1,1,n);
		}
		else {
			cin>>x>>y;
		    cout<<query(x,y,1,1,n)<<endl;
		}
	}
	return 0;
}

2024/4/7 20:52
加载中...