bdfz_2024_summer/day14/P3372/P3372.cpp

122 lines
2.6 KiB
C++
Raw Normal View History

2024-08-18 08:39:13 +00:00
#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);
}