线段树求助!
  • 板块学术版
  • 楼主Lovable_Wind
  • 当前回复16
  • 已保存回复16
  • 发布时间2021/8/5 22:52
  • 上次更新2023/11/4 11:52:52
查看原帖
线段树求助!
112631
Lovable_Wind楼主2021/8/5 22:52
#include<bits/stdc++.h>
using namespace std;
const double pi=3.14;
const int inf=0x3f3f3f3f;
const int NIL=-1;
#define f(i,l,r) for(int i=l;i<=r;i++)
struct Tree{
	int l,r,mid;
	int value;
	int lazytag;
}T[100010];
int n,q;
int a[100010];
int sizex(int x){
	return T[x].r-T[x].l+1;
}
void Pushup(int x){
	T[x].value=T[x*2+1].value+T[x*2+1].value;
}
void pushdown(int x){
	if (T[x].l<T[x].r){
		T[x*2].lazytag+=T[x].lazytag;
		T[x*2+1].lazytag+=T[x].lazytag;
		//////////
		T[x*2].value+=T[x*2].lazytag*sizex(x*2);
		T[x*2+1].value+=T[x*2+1].lazytag*sizex(x*2+1);
		//////////
		T[x].lazytag=0;
	}
}
void Prepare_Tree(int x,int l,int r){ 
	T[x].l=l;
	T[x].r=r;
	T[x].lazytag=0;
	if (l==r){
		T[x].value=a[l];
	}else{
		T[x].mid=(l+r)/2;
		Prepare_Tree(x*2,l,T[x].mid);
		Prepare_Tree(x*2+1,T[x].mid+1,r);
		Pushup(x);
	}
}//建树 x为线段树上编号 l,r 为线段区间标记
void Update(int x,int l,int r,long long add){
	if (T[x].l==l&&T[x].r==r){
		T[x].value+=sizex(x)*add;
		T[x].lazytag+=add;
		return;
	}
	pushdown(x);
	if (l>T[x].mid) Update(x*2+1,l,r,add);
	else if (r<=T[x].mid) Update(x*2,l,r,add);
	else{
		Update(x*2,l,T[x].mid,add);
		Update(x*2+1,T[x].mid+1,r,add);
	}
	Pushup(x);
}
long long Getsum(int x,int l,int r){
	if (T[x].l==l&&T[x].r==r){
		return T[x].value;
	}
	pushdown(x);
	if (l>T[x].mid) return Getsum(x*2+1,l,r);
	else if (r<=T[x].mid) return Getsum(x*2,l,r);
	else{
		long long res=0;
		res+=Getsum(x*2,l,T[x].mid);
		res+=Getsum(x*2+1,T[x].mid+1,r);
		return res;
	}
}
int read()
{
    int ans=0,flag=1;
    char ch=getchar();
    while( (ch>'9' || ch<'0') && ch!='-' ) ch=getchar();
    if(ch=='-') flag=-1,ch=getchar();
    while(ch>='0' && ch<='9') ans=ans*10+ch-'0',ch=getchar();
    return ans*flag;
}
int main()
{
	n=read(),q=read();
	for(int i=1;i<=n;i++)
		a[i]=read();
	Prepare_Tree(1,1,n);
	for(int i=1;i<=q;i++){
		int opt=read();
		if(opt==1){
			int f=read(),g=read();
			long long h=read();
			Update(1,f,g,h);
		}else{
			int f=read(),g=read();
			long long res=Getsum(1,f,g);
			cout<<res<<endl;
		}
	}
}

输入

5 5
1 5 4 2 3
2 2 4
1 2 3 2
2 3 4
1 1 5 1
2 1 4

输出

11
10
18
2021/8/5 22:52
加载中...