P3372 【模板】线段树 1
#include<cstdio>
#include<iostream>
using namespace std;
#define MAXN 1000099
#define LLD long long int
#define ls id*2
#define rs id*2+1
int n,m,opt,x,y,k;
int A[MAXN],B[MAXN];
LLD num[MAXN],lazy[MAXN];
void Build(int id,int L,int R)
{
A[id]=L;
B[id]=R;
if(L==R)
{
cin>>num[id];
return ;
}
int mid=(L+R)/2;
Build(ls,L,mid);
Build(rs,mid+1,R);
num[id]=num[ls]+num[rs];
}
void down(int id)
{
num[id]+=lazy[id]*(B[id]-A[id]+1);
if(A[id]<B[id])
{
lazy[ls]+=lazy[id];
lazy[rs]+=lazy[id];
}
lazy[id]=0;
}
void add(int id,int L,int R,LLD val)
{
down(id);
if(A[id]==L && B[id]==R)
{
lazy[id]+=val;
return ;
}
int mid=(A[id]+B[id])/2;
if(R<=mid) add(ls,L,R,val);
else if(mid<L) add(rs,L,R,val);
else
{
add(ls,L,mid,val);
add(rs,mid+1,R,val);
}
num[id]=num[ls]+lazy[ls]*(B[ls]-A[ls]+1)+num[rs]+lazy[rs]*(B[rs]-A[rs]+1);
}
LLD sum(int id,int L,int R)
{
down(id);
if(A[id]==L && B[id]==R) return num[id];
int mid=(A[id]+B[id])/2;
if(R<=mid) return sum(ls,L,R);
else if(mid<L) return sum(rs,L,R);
else
{
return sum(ls,L,mid)+sum(rs,mid+1,R);
}
}
int main()
{
freopen("test.in","r",stdin);
cin>>n>>m;
Build(1,1,n);
for(int i=1; i<=m; i++)
{
cin>>opt;
if(opt==1)
{
cin>>x>>y>>k;
add(1,x,y,k);
}
else
{
cin>>x>>y;
cout<<sum(1,x,y)<<endl;
}
}
return 0;
}