122 lines
2.6 KiB
C++
122 lines
2.6 KiB
C++
|
#include <cctype>
|
||
|
#include <cstddef>
|
||
|
#include <cstdio>
|
||
|
#include <iostream>
|
||
|
using namespace std;
|
||
|
|
||
|
template<size_t MAX>
|
||
|
class SegTree{
|
||
|
public:
|
||
|
SegTree(int arr[],int n);
|
||
|
void add(int l,int r,int c);
|
||
|
int search(int l,int r);
|
||
|
private:
|
||
|
int n;
|
||
|
int t[MAX*4+1];
|
||
|
int l[MAX*4+1];
|
||
|
private:
|
||
|
void build(int s,int e,int now,int arr[]);
|
||
|
void update(int s,int e,int now,int l,int r,int c);
|
||
|
int getSum(int s,int e,int now,int l,int r);
|
||
|
};
|
||
|
int readInt();
|
||
|
|
||
|
const int MAX_N=1e5+5;
|
||
|
int arr[MAX_N];
|
||
|
|
||
|
int main(){
|
||
|
const int n=readInt(),m=readInt();
|
||
|
for(int i=1;i<=n;i++){
|
||
|
arr[i]=readInt();
|
||
|
}
|
||
|
SegTree<MAX_N> s(arr,n);
|
||
|
for(int i=1;i<=m;i++){
|
||
|
const int z=readInt(),x=readInt(),y=readInt();
|
||
|
if(z==1){
|
||
|
const int k=readInt();
|
||
|
s.add(x, y, k);
|
||
|
}else{
|
||
|
cout<<s.search(x, y)<<endl;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int readInt(){
|
||
|
int x=0,w=1;
|
||
|
char ch=0;
|
||
|
while(!isdigit(ch)){
|
||
|
if(ch=='-')w=-1;
|
||
|
ch=getchar();
|
||
|
}
|
||
|
while(isdigit(ch)){
|
||
|
x=x*10+(ch-'0');
|
||
|
ch=getchar();
|
||
|
}
|
||
|
return x*w;
|
||
|
}
|
||
|
|
||
|
template<size_t n>
|
||
|
int SegTree<n>::getSum(int s,int e,int now,int l,int r){
|
||
|
if(l<=s&&e<=r){
|
||
|
return t[now];
|
||
|
}
|
||
|
int m=(e-s)/2+s;
|
||
|
if(this->l[now]){
|
||
|
t[now*2]+=this->l[now]*(m-s+1);
|
||
|
t[now*2+1]+=this->l[now]*(e-(m+1)+1);
|
||
|
this->l[now*2]+=this->l[now];
|
||
|
this->l[now*2+1]+=this->l[now];
|
||
|
this->l[now]=0;
|
||
|
}
|
||
|
int sum=0;
|
||
|
if(l<=m)sum=getSum(s, m, now, l, r);
|
||
|
if(m+1<=r)sum+=getSum(m+1, e, now, l, r);
|
||
|
return sum;
|
||
|
}
|
||
|
|
||
|
template<size_t n>
|
||
|
int SegTree<n>::search(int l,int r){
|
||
|
return getSum(1, n, 1, l, r);
|
||
|
}
|
||
|
|
||
|
template<size_t n>
|
||
|
void SegTree<n>::update(int s,int e,int now,int l,int r,int c){
|
||
|
if(l<=s&&e<=r){
|
||
|
t[now]+=(e-s+1)*c;
|
||
|
this->l[now]+=c;
|
||
|
return;
|
||
|
}
|
||
|
int m=(e-s)/2+s;
|
||
|
if(this->l[now]&&s!=e){
|
||
|
t[now*2]+=this->l[now]*(m-s+1);
|
||
|
t[now*2+1]+=this->l[now]*(e-(m+1)+1);
|
||
|
this->l[now*2]+=this->l[now];
|
||
|
this->l[now*2+1]+=this->l[now];
|
||
|
this->l[now]=0;
|
||
|
}
|
||
|
if(l<=m)update(s, m, now, l, r, c);
|
||
|
if(m+1<=r)update(m+1, e, now, l, r, c);
|
||
|
t[now]=t[now*2]+t[now*2+1];
|
||
|
}
|
||
|
|
||
|
template<size_t n>
|
||
|
void SegTree<n>::add(int l,int r,int c){
|
||
|
update(1, n, 1, l, r, c);
|
||
|
}
|
||
|
|
||
|
template<size_t n>
|
||
|
void SegTree<n>::build(int s,int e,int now,int arr[]){
|
||
|
if(s==e){
|
||
|
t[now]=arr[s];
|
||
|
return;
|
||
|
}
|
||
|
int m=s+(e-s)/2;
|
||
|
build(s, m, now*2, arr);
|
||
|
build(m+1, e, now*2+1, arr);
|
||
|
t[now]=t[now*2]+t[now*2+1];
|
||
|
}
|
||
|
|
||
|
template<size_t n>
|
||
|
SegTree<n>::SegTree(int arr[],int n):n(n){
|
||
|
build(1, n, 1, arr);
|
||
|
}
|