社区讨论
15 pts求调
P3372【模板】线段树 1参与者 3已保存回复 10
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 10 条
- 当前快照
- 1 份
- 快照标识符
- @mjvmtuh3
- 此快照首次捕获于
- 2026/01/02 00:01 2 个月前
- 此快照最后确认于
- 2026/01/04 18:35 2 个月前
自认为本人已开
CPPlong long。//998244353
#include<bits/stdc++.h>
#define itn int
#define int long long
using namespace std;
const int N=1e5+10;
itn n,m,a[N],opt,x,y,k;
struct node
{
itn l,r,sum,add=0;
}tree[4*N];
inline void pushup(int u)
{
tree[u].sum=tree[u*2].sum+tree[u*2+1].sum;
}
inline void pushdown(itn u)
{
if(tree[u].add)//有懒标记,下传
{
tree[u*2].sum+=(tree[u*2].r-tree[u*2].l+1)*tree[u].add;
tree[u*2+1].sum+=(tree[u*2].r-tree[u*2].l+1)*tree[u].add;
tree[u*2].add+=tree[u].add;
tree[u*2+1].add+=tree[u].add;
tree[u].add=0;//已经下传完懒标记,清除原节点懒标记
}
}
inline void build(int fa,int l,int r)
{
tree[fa].l=l;
tree[fa].r=r;
tree[fa].sum=a[l];
if(l==r)//为叶子节点
{
return ;
}
build(fa*2,l,(l+r)/2);//建左子树
build(fa*2+1,(l+r)/2+1,r);//建右子树
pushup(fa);
}
inline void change(int fa,itn l,int r,int num)
{
if(l<=tree[fa].l&&tree[fa].r<=r)//改变的区间完全覆盖某个节点的区间
{
tree[fa].sum+=(tree[fa].r-tree[fa].l+1)*num;
tree[fa].add+=num;
return ;
}
pushdown(fa);
if(l<=(tree[fa].l+tree[fa].r)/2)//如果要更新的区间的左端点在当前节点的左节点区间内
{
change(fa*2,l,r,num);
}
if(r>(tree[fa].l+tree[fa].r)/2)//如果要更新的区间的右端点在当前节点的右节点区间内
{
change(fa*2+1,l,r,num);
}
pushup(fa);
}
inline int query(itn fa,itn l,itn r)
{
itn sum=0;
if(l<=tree[fa].l&&tree[fa].r<=r)//查询的区间完全覆盖某个节点的区间
{
return tree[fa].sum;
}
pushdown(fa);//注意这里也要下传懒标记!!!
if(l<=(tree[fa].l+tree[fa].r)/2)//如果要查询的区间的左端点在当前节点的左节点区间内
{
sum+=query(fa*2,l,r);
}
if(r>(tree[fa].l+tree[fa].r)/2)//如果要查询的区间的右端点在当前节点的右节点区间内
{
sum+=query(fa*2+1,l,r);
}
return sum;
}
signed main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
build(1,1,n);
while(m--)
{
cin>>opt;
if(opt==1)
{
cin>>x>>y>>k;
change(1,x,y,k);
}
else
{
cin>>x>>y;
cout<<query(1,x,y)<<endl;
}
}
}
回复
共 10 条回复,欢迎继续交流。
正在加载回复...