社区讨论
求助!
P3372【模板】线段树 1参与者 2已保存回复 2
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 2 条
- 当前快照
- 1 份
- 快照标识符
- @locrwfl9
- 此快照首次捕获于
- 2023/10/30 18:44 2 年前
- 此快照最后确认于
- 2023/11/05 05:29 2 年前
CPP
//P3372
#include <cstdio>
const int maxn=100005;
int a[maxn],t[maxn<<2],lazy[maxn<<2];
void up(int node){
//从子树更新节点
t[node]=t[node<<1]+t[node<<1|1];
return;
}
void down(int node){
//将节点的lt更新到子树上
if(lazy[node]){
lazy[node<<1]+=lazy[node];
lazy[node<<1|1]+=lazy[node];
t[node<<1]+=lazy[node];
t[node<<1|1]+=lazy[node];
lazy[node]=0;
}
return;
}
void buildtree(int node,int l,int r){
//建树
if(l==r){
t[node]=a[l];
return;
}
int m=l+((r-l)>>1);
buildtree(node<<1,l,m);
buildtree(node<<1|1,m+1,r);
up(node);
return;
}
int query(int l1,int r1,int l,int r,int node){
//区间查询
if(l1<=l && r<=r1)
return t[node];
down(node);
int ret=0,m=l+((r-l)>>1);
if(l1<=m) ret+=query(l1,r1,l,m,node<<1);
if(r1>m) ret+=ret,query(l1,r1,m+1,r,node<<1|1);
return ret;
}
void add(int l1,int r1,int v,int l,int r,int node){
//区间添加
if(l1<=l && r<=r1){
lazy[node]+=v;
t[node]+=v;
return;
}
down(node);
int m=l+((r-l)>>1);
if(l1<=m) add(l1,r1,v,l,m,node<<1);
if(m<r1) add(l1,r1,v,m+1,r,node<<1|1);
up(node);
return;
}
int main(){
int n,m,f,x,y,k;
scanf("%d %d",&n,&m);
for(int i=1; i<=n; ++i)
scanf("%d",&a[i]);
buildtree(1,1,n);
for(int i=1; i<=m; ++i){
scanf("%d",&f);
switch(f){
case 1:
scanf("%d %d %d",&x,&y,&k);
add(x,y,k,1,n,1);
break;
case 2:
scanf("%d %d",&x,&y);
printf("%d\n",query(x,y,1,n,1));
break;
default:
break;
}
}
return 0;
}
样例都过不了
回复
共 2 条回复,欢迎继续交流。
正在加载回复...