线段树模板,求助
查看原帖
线段树模板,求助
912445
ZHANGyutao123楼主2023/11/23 13:25
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=100003;
int n,m,k,a[N];
long long tree[N<<2],tag[N<<2];
inline int ls(int p){return p<<1;}
inline int rs(int p){return p<<1|1;}
inline void push_up(int p)
{
	tree[p]=tree[ls(p)]+tree[rs(p)]; 
}
inline void build(int l,int r,int p)
{
	if(l==r)
	{
		tree[p]=a[l]*1ll;
		return;
	}
	int mid=(l+r)>>1;
	build(l,mid,ls(p));
	build(mid+1,r,rs(p)); 
	push_up(p);
}
inline void addtag(int p,int pl,int pr,int d)
{
	tag[p]+=d*1ll;
	tree[p]+=(pr-pl+1)*d*1ll;
}
inline void push_down(int p,int pl,int pr)
{
	if(tag[p])
	{
		int mid=(pl+pr)>>1;
		addtag(ls(p),pl,mid,tag[p]);
		addtag(rs(p),mid+1,pr,tag[p]);
		tag[p]=0;
	}
}
inline void add(int l,int r,int pl,int pr,int p,int d)
{
	if(l<=pl&&pr<=r)
	{
		addtag(p,pl,pr,d);
		return;
	}
	push_down(p,pl,pr);
	int mid=(pl+pr)>>1;
	if(l<=mid)add(l,r,pl,mid,ls(p),d);
	if(r>mid) add(l,r,mid+1,pr,rs(p),d);
	push_up(p);
}
inline long long sum(int l,int r,int pl,int pr,int p)
{
	if(pl>=l&&pr<=r)return tree[p];
	int mid=(pl+pr)>>1;
	long long ans=0;
	if(l<=mid) ans+=sum(l,r,pl,mid,ls(p));
	if(r>mid) ans+=sum(l,r,mid+1,pr,rs(p));
	return ans;
}
int main() {
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	build(1,n,1);
	while(m--)
	{
		int op,x,y,k;
		scanf("%d",&op);
		if(op==1)
		{
			scanf("%d%d%d",&x,&y,&k);
			add(x,y,1,n,1,k);
		}
		else
		{
			scanf("%d%d",&x,&y);
			printf("%lld\n",sum(x,y,1,n,1));
		}
	}
	return 0;
}
2023/11/23 13:25
加载中...