求助求助,线段树又挂了
查看原帖
求助求助,线段树又挂了
67618
haooo楼主2020/6/15 18:59
#include<bits/stdc++.h>
using namespace std;
const int SIZE=100005;
int n,m;
struct Tree{
	int l,r;
	long long sum,add;
	#define l(x) t[x].l
	#define r(x) t[x].r
	#define sum(x) t[x].sum
	#define add(x) t[x].add
}t[4*SIZE];
long long a[SIZE];
void build(int p,int l,int r){//建树 
	l(p)=l,r(p)=r;
	if(l==r){
		sum(p)=a[l];
		return;
	}
	int mid=(l+r)>>1;
	build(p<<1,l,mid);//左节点 
	build(p<<1|1,mid+1,r);//右节点 
	sum(p)=sum(p<<1)+sum(p<<1|1);
}
void spread(int p){//下传延迟标记 
	if(add(p)){
		sum(p<<1)+=add(p)*(r(p<<1)-l(p<<1)+1);
		sum(p<<1|1)+=add(p)*(r(p<<1|1)-l(p<<1|1)+1);
		add(p<<1)+=add(p);
		add(p<<1|1)+=add(p);
		add(p)=0;
	}
}
void change(int p,int l,int r,long long x){
	if(l<=l(p)&&r(p)<=r){//完全覆盖 
		add(p)+=x;
		sum(x)+=(long long)x*(r(p)-l(p)+1);
		return;
	}
	spread(p);//向下传递 
	int mid=(l(p)+r(p))>>1;
	if(l<=mid){//需要修改左区间 
		change(p<<1,l,r,x);
	//	cout<<l<<" "<<mid<<endl;
	}
	
	if(r>mid){//需要修改右区间 
		change(p<<1|1,l,r,x);
	//	cout<<mid+1<<" "<<r<<endl;
	}
	sum(p)=sum(p<<1)+sum(p<<1|1);
}
long long ask(int p,int l,int r){
	if(l<=l(p)&&r>=r(p))	return sum(p);//完全覆盖 
	spread(p);
	int mid=(l(p)+r(p))>>1;
	long long val=0;
	if(l<=mid)	val+=ask(p<<1,l,r);//需要查询左区间 
	if(mid<r)	val+=ask(p<<1|1,l,r);//需要查询右区间 
	return val;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++){
		scanf("%lld",&a[i]);
	}
	build(1,1,n);
	/*
	for(int i=1;i<=n;i++){
		for(int j=i;j<=n;j++){
			cout<<i<<" "<<j<<" "<<ask(1,i,j)<<"\n";
		}
	}*/
	while(m--){
		int op;
		int l,r,d;
		scanf("%d%d%d",&op,&l,&r);
		if(op==1){
			scanf("%d",&d);
			change(1,l,r,d);/*
			for(int i=1;i<=n;i++){
				cout<<ask(1,i,i)<<" ";
			}
			cout<<endl;*/
			continue;
		}		
		printf("%lld\n",ask(1,l,r));
	//	for(int i=1;i<=5;i++){
	//		printf("%lld ",ask(1,i,i));
	//	}
	//	cout<<endl;
	}
	return 0;
}
2020/6/15 18:59
加载中...