社区讨论
问
P3372【模板】线段树 1参与者 2已保存回复 4
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @mibljhni
- 此快照首次捕获于
- 2025/11/23 18:50 4 个月前
- 此快照最后确认于
- 2025/11/23 20:08 4 个月前
AC代码:
CPP#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
#define ll long long
#define LC 2*cur
#define RC 2*cur+1
ll a[N];
struct Node{
int l,r;
ll value,tag;
int len(){
return r-l+1;
}
}tree[N*4];
void pushup(int cur){
tree[cur].value=tree[LC].value+tree[RC].value;
}
void build(int cur,int l,int r){
tree[cur].l=l,tree[cur].r=r;
if(l==r){
tree[cur].value=a[l];
return;
}
int mid=(l+r)/2;
build(LC,l,mid);
build(RC,mid+1,r);
pushup(cur);
}
void work(int cur,ll delta){
tree[cur].value+=(tree[cur].len()*delta);
tree[cur].tag+=delta;
}
void pushdown(int cur){
if(tree[cur].tag>0){
work(LC,tree[cur].tag),work(RC,tree[cur].tag);
tree[cur].tag=0;
}
}
void update(int cur,int l,int r,ll delta){
if(l<=tree[cur].l&&r>=tree[cur].r){
work(cur,delta);
return;
}
pushdown(cur);
int mid=(tree[cur].r+tree[cur].l)/2;
if(mid>=l)update(LC,l,r,delta);
if(mid<r)update(RC,l,r,delta);
pushup(cur);
}
ll query(int cur,int l,int r){
if(l<=tree[cur].l&&r>=tree[cur].r)return tree[cur].value;
pushdown(cur);
ll ans=0;
int mid=(tree[cur].r+tree[cur].l)/2;
if(mid>=l)ans+=query(LC,l,r);
if(mid<r)ans+=query(RC,l,r);
return ans;
}
int n,m;
int main(){
cin >> n >> m;
for(int i=1;i<=n;i++){
cin >> a[i];
}
build(1,1,n);
for(int i=1;i<=m;i++){
int op,x,y;
ll k;
cin >> op >> x >> y;
if(op==1){
cin >> k;
update(1,x,y,k);
}
else {
cout << query(1,x,y) << '\n';
}
}
return 0;
}
为啥query和update函数中向下递推的部分不能写成这样
CPPif(mid>=l)ans+=query(LC,l,mid);
if(mid<r)ans+=query(RC,mid+1,r);
以及这样
CPPif(mid>=l)update(LC,l,mid,delta);
if(mid<r)update(RC,mid+1,r,delta);
这样写是0pts但我不知道为啥
回复
共 4 条回复,欢迎继续交流。
正在加载回复...