P3372 【模板】线段树 1
题目描述
如题,已知一个数列,你需要进行下面两种操作:
- 将某区间每一个数加上 \(k\)。
- 求出某区间每一个数的和。
输入格式
第一行包含两个整数 \(n, m\),分别表示该数列数字的个数和操作的总个数。
第二行包含 \(n\) 个用空格分隔的整数,其中第 \(i\) 个数字表示数列第 \(i\) 项的初始值。
接下来 \(m\) 行每行包含 \(3\) 或 \(4\) 个整数,表示一个操作,具体如下:
1 x y k:将区间 \([x, y]\) 内每个数加上 \(k\)。2 x y:输出区间 \([x, y]\) 内每个数的和。
输出格式
输出包含若干行整数,即为所有操作 2 的结果。
样例 #1
样例输入 #1
5 5
1 5 4 2 3
2 2 4
1 2 3 2
2 3 4
1 1 5 1
2 1 4
样例输出 #1
11
8
20
提示
对于 \(30\%\) 的数据:\(n \le 8\),\(m \le 10\)。
对于 \(70\%\) 的数据:\(n \le {10}^3\),\(m \le {10}^4\)。
对于 \(100\%\) 的数据:\(1 \le n, m \le {10}^5\)。
保证任意时刻数列中所有元素的绝对值之和 \(\le {10}^{18}\)。
【样例解释】

分析
线段树模板题
#include<bits/stdc++.h>
#define int long long
using namespace std;
inline int read(){
int x=0,f=1;
char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=(x<<1)+(x<<3)+(c^48);c=getchar();}
return x*f;
}
int n,m,a[100005],t[100005<<2],tag[100005<<2];
inline int ls(int p){return p<<1;}
inline int rs(int p){return p<<1|1;}
inline void pushup(int x){t[x]=t[ls(x)]+t[rs(x)];}
void build(int l,int r,int num){
if(l==r){t[num]=a[l];return;}
int mid=l+r>>1;
build(l,mid,num<<1),build(mid+1,r,num<<1|1);
pushup(num);
}
inline void f(int num,int l,int r,int k){tag[num]+=k,t[num]+=k*(r-l+1);}
inline void pushdown(int num,int l,int r){
int mid=l+r>>1;
f(ls(num),l,mid,tag[num]),f(rs(num),mid+1,r,tag[num]);
tag[num]=0;
}
inline void update(int nl,int nr,int l,int r,int num,int k){
if(nl<=l&&nr>=r){
tag[num]+=k,t[num]+=k*(r-l+1);
return;
}
pushdown(num,l,r);
int mid=l+r>>1;
if(nl<=mid)update(nl,nr,l,mid,ls(num),k);
if(nr>mid)update(nl,nr,mid+1,r,rs(num),k);
pushup(num);
}
inline int query(int nl,int nr,int l,int r,int num){
if(nl<=l&&nr>=r)return t[num];
int mid=l+r>>1,res=0;
pushdown(num,l,r);
if(nl<=mid)res+=query(nl,nr,l,mid,ls(num));
if(nr>mid)res+=query(nl,nr,mid+1,r,rs(num));
return res;
}
signed main(){
n=read(),m=read();
for(int i=1;i<=n;i++)a[i]=read();
build(1,n,1);
for(int i=1,opt,x,y,k;i<=m;i++){
opt=read();
if(opt==1){
x=read(),y=read(),k=read();
update(x,y,1,n,1,k);
}else{
x=read(),y=read();
cout<<query(x,y,1,n,1)<<endl;
}
}
return 0;
}

浙公网安备 33010602011771号