这里没判 mid,不知道线段树那题您有没有判?
by 朦胧_XY @ 2023-11-01 17:14:32
判 mid 了应该就不用判边界。@[RingTouSou](/user/1034242)
by 朦胧_XY @ 2023-11-01 17:17:45
```cpp
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define N 100005
#define LL long long
#define lc u<<1 //除二
#define rc u<<1|1 //除二+1
LL w[N];
struct Tree
{
LL l,r,sum,add; //线段树
}tr[N*4];
void pushup(LL u){ //上传 (父节点)
tr[u].sum=tr[lc].sum+tr[rc].sum;
}
void pushdown(LL u) //往下传 (父节点)
{
if(tr[u].add)
{
tr[lc].sum+=tr[u].add*(tr[lc].r-tr[lc].l+1);
tr[rc].sum+=tr[u].add*(tr[rc].r-tr[rc].l+1);
tr[lc].add+=tr[u].add;
tr[rc].add+=tr[u].add;
tr[u].add=0;
}
}
void build(LL u,LL l,LL r) //建树 (父节点,左端点,右端点)
{
tr[u]={l,r,w[l],0};
if(l==r) return;
LL m=l+r>>1; //除二
build(lc,l,m);
build(rc,m+1,r);
pushup(u);
}
void change(LL u,LL l,LL r,LL k) //区间修(父节点,总左端点,总右端点,每段加多少)
{
if(l>tr[u].r || r<tr[u].l) return;
if(l<=tr[u].l&&tr[u].r<=r)
{
tr[u].sum+=(tr[u].r-tr[u].l+1)*k;
tr[u].add+=k; //先用懒标记存起来
return; //如果被全包含,直接返回
}
LL m=tr[u].l+tr[u].r>>1; //除二
pushdown(u);
if(l<=m) change(lc,l,r,k);
if(r>m) change(rc,l,r,k);
pushup(u);
}
LL query(LL u,LL l,LL r){ //区间查找(输出) (父节点,总左端点,总右端点)
if(l<=tr[u].l&&tr[u].r<=r) return tr[u].sum;
LL m=tr[u].l+tr[u].r>>1; //除二
pushdown(u);
LL sum=0;
if(l<=m) sum+=query(lc,l,r);
if(r>m) sum+=query(rc,l,r);
return sum;
}
int main()
{
int n,m,op,x,y,k;
cin>>n>>m;
for(int i=1;i<=n;++i) cin>>w[i];
build(1,1,n);
while(m--)
{
cin>>op>>x>>y;
if(op==2) cout<<query(1,x,y)<<endl;
else cin>>k,change(1,x,y,k);
}
return 0;
}
```
@[朦胧_XY](/user/358971)
这是那道题的
by RingTouSou @ 2023-11-01 17:27:38
@[朦胧_XY](/user/358971) 刚好在学这个,请问mid什么意思
by RingTouSou @ 2023-11-01 17:30:07
你要是写
```cpp
if(l<=m) change(lc,l,r,k);
if(r>m) change(rc,l,r,k);
```
这种就不需要判
by jijidawang @ 2023-11-01 17:34:22
@[RingTouSou](/user/1034242) 就是特判 `if(l<=m)` 和 `if(r>m)` 。
by 朦胧_XY @ 2023-11-01 17:35:05
@[朦胧_XY](/user/358971) 谢谢,关注了
by RingTouSou @ 2023-11-01 20:44:11