求助,手搓的线段树,样例都过不去
查看原帖
求助,手搓的线段树,样例都过不去
1025217
fe117楼主2024/5/19 09:31
//P3372 线段树1 Unaccepted 
#include <iostream> 
#define ll long long
using namespace std;
struct jd{
	ll l,r,sum,tag=0;
};
jd tr[400005]={};
ll a[100005]={};
void build(ll l,ll r,ll n){
	tr[n].l=l;
	tr[n].r=r;
	if(l==r){
		tr[n].sum=a[l];
		return;
	}
	ll mid=(l+r)/2;
	build(l,mid,2*n);
	build(mid+1,r,2*n+1);
	tr[n].sum=tr[2*n].sum+tr[2*n+1].sum;
}
void pushtag(ll l,ll r,ll n,ll tag){
	if(tr[n].l==tr[n].r){
		tr[n].sum+=tag;
		return;
	}
	if(tr[2*n].r<l){
		pushtag(l,r,2*n+1,tag);
		return;
	}
	if(tr[2*n].r>=r){
		pushtag(l,r,2*n,tag);
		return;
	} 
	if(tr[n].l==l&&tr[n].r==r){
		tr[n].tag+=tag;
		return;
	}
	pushtag(l,tr[2*n].r,2*n,tag);
	pushtag(tr[2*n+1].l,r,2*n+1,tag);
}
ll getsum(ll l,ll r,ll n){
	if(tr[n].l==tr[n].r){
		tr[n].sum+=tr[n].tag;
		tr[n].tag=0;
		return tr[n].sum;
	}
	if(tr[2*n].r<l){
		return getsum(l,r,2*n+1);
	}
	if(tr[2*n].r>=r){
		return getsum(l,r,2*n);
	} 
	/*if(tr[n].l==l&&tr[n].r==r){
		return tr[n].sum+tr[n].tag*(r-l+1);
	}*/
	tr[2*n].tag+=tr[n].tag;
	tr[2*n+1].tag+=tr[n].tag;
	tr[n].tag=0;
	return getsum(l,tr[2*n].r,2*n)+getsum(tr[2*n+1].l,r,2*n+1);
}
int main(){
	int n,m,p,x,y,k;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i];
	}
	build(1,n,1);
	for(int i=0;i<m;i++){
		cin>>p;
		if(p==1){
			cin>>x>>y>>k;
			pushtag(x,y,1,k);
		}
		else{
			cin>>x>>y;
			cout<<getsum(x,y,1)<<endl;
		}
	}
	return 0;
}
2024/5/19 09:31
加载中...