covonant @ 2024-11-14 13:20:02
QwQ
#include<iostream>
#define maxn 100005
using namespace std;
int m,n;
int a[maxn],w[maxn*4];
int lzy[maxn*4];
void pushup(int u){
w[u]=w[u*2]+w[u*2+1];
}
void build(int u,int L,int R){//建立[L,R]区间的线段树
if(L==R){
w[u]=a[L];
return;
}
int M=(L+R)/2;
build(u*2,L,M);
build(u*2+1,M+1,R);
pushup(u);
}
//单点操作
int query1(int u,int L,int R,int k){//查找排名为k的数字
if(L==R) return w[u];
int M=(L+R)/2;
if(k<=M){//在左子树
return query1(u*2,L,M,k);
}else{
return query1(u*2,M+1,R,k);
}
}
void update1(int u,int L,int R,int k,int x){//将第k个数字修改为 x
if(L==R){
w[u]=x;
return;
}
int M=(L+R)/2;
if(k<=M){
update1(u*2,L,M,k,x);
}else update1(u*2+1,M+1,R,k,x);
pushup(u);
}
//区间操作
void maketag(int u,int len,int x){//创建一个lzy
w[u]+=len*x;
lzy[u]=x;
}
bool Inrange(int L,int R,int l,int r){//判断区间[l,r]是否包含于[L,R]
return L<=l&&r<=R;
}
bool Outrange(int L,int R,int l,int r){//判断区间[l,r]是否与[L,R]无交集
return R<l||L>r;
}
void pushdown(int u,int L,int R){
//下发lzy
int M=(L+R)/2;
maketag(u*2,M-L+1,lzy[u]);
maketag(u*2+1,R-M,lzy[u]);
lzy[u]=0;
}
int query2(int u,int L,int R,int l,int r){//查找区间[l,r]的值
if(Inrange(L,R,l,r)){
return w[u];
}
if(!Outrange(L,R,l,r)){
int M=(L+R)/2;
pushdown(u,L,R);
return query2(u*2,L,M,l,r)+query2(u*2+1,M+1,R,l,r);
}else return 0;
}
void update2(int u,int L,int R,int l,int r,int k){//将[l,r]区间内的数字全部加上 k
if(Inrange(L,R,l,r)){
maketag(u,R-l+1,k);
return;
}
if(!Outrange(L,R,l,r)){
int M=(L+R)/2;
pushdown(u,L,R);
update2(u*2,L,M,l,r,k);
update2(u*2+1,M+1,R,l,r,k);
}
pushup(u);
return;
}
int main(){
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
build(1,1,n);
while(m--){
int op,x,y,k;
cin>>op>>x>>y;
if(op==1){
cin>>k;
update2(1,1,n,x,y,k);
}
else{
cout<<query2(1,1,n,x,y)<<'\n';
}
}
return 0;
}
by 羊叫兽同学 @ 2024-11-14 14:13:11
void maketag(int u,int len,int x){//创建一个lzy
w[u]+=len*x;
lzy[u]=x;
}
lzy[u]+=x