社区讨论
萌新妹子,刚学线段树,样例不过,求调
P3372【模板】线段树 1参与者 4已保存回复 4
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @lo7qe4oo
- 此快照首次捕获于
- 2023/10/27 06:03 2 年前
- 此快照最后确认于
- 2023/10/27 06:03 2 年前
悬赏关注一个
CPP#include<iostream>
using namespace std;
typedef long long ll;
const int maxn=1e6;
struct node{
ll sum;
ll tag;
}tree[maxn<<2];
ll arr[maxn+5];
void pushUp(ll root){
tree[root].sum=tree[root<<1].sum+tree[root<<1|1].sum;
return ;
}
void pushDown(ll root,ll ln,ll rn){
if(tree[root].tag){//Has tag
tree[root<<1].tag+=tree[root].tag;
tree[root<<1|1].tag+=tree[root|1].tag;
tree[root<<1].sum+=ln*tree[root].tag;
tree[root<<1|1].sum+=rn*tree[root].tag;
tree[root].tag=0;
}
return ;
}
void build(ll l,ll r,ll root){
if(l==r){
tree[root].sum=arr[l];
return ;
}
ll mid=(l+r)>>1;
build(l,mid,root<<1);
build(mid+1,r,root<<1|1);
pushUp(root);
return ;
}
void updateQ(ll l,ll r,ll L,ll R,ll v,ll root){//区间更新
if(L<=l && r<=R){
tree[root].sum+=(r-l+1)*v;
tree[root].tag+=v;//Lazy tag
return ;
}
ll mid=(l+r)>>1;
ll ln=mid-l+1,rn=r-mid;
pushDown(root,ln,rn);
if(L<=mid){
updateQ(l,mid,L,R,v,root<<1);
}
if(R>mid){
updateQ(mid+1,r,L,R,v,root<<1|1);
}
pushUp(root);//update
return ;
}
ll query(int l,int r,int L,int R,int root){
ll sum=0;
if(L<=l && r<=R){
return tree[root].sum;
}
ll mid=(l+r)>>1;
ll ln=mid-l+1;
ll rn=r-mid;
pushDown(root,ln,rn);
if(L<=mid){
sum+=query(l,mid,L,R,root>>1);
}
if(mid<R){
sum+=query(mid+1,r,L,R,root>>1|1);
}
return sum;
}
int main(){
ll n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>arr[i];
}
build(1,n,1);
int t=0,l,r,v;
while(m--){
cin>>t;
if(t==1){
cin>>l>>r>>v;
updateQ(1,n,l,r,v,1);
}else{
cin>>l>>r;
cout<<query(1,n,l,r,1)<<endl;
}
}
}
回复
共 4 条回复,欢迎继续交流。
正在加载回复...