Live2D

[线段树] (e) Luogu3372 (模版题)

(e) luogu3372 【模板】线段树 1

如在阅读本文时遇到不懂的部分,请在评论区询问,或跳转 线段树总介绍

 

此题过水不予讲解

代码(不知道为什么当时long long用不了就用了unsigned long)

/*luogu3372*/
/*模版*/

#include<iostream>
#include<cstdio>
using namespace std;
typedef unsigned long int LL;
const LL N=1e6+5;
LL n,m,a[N],v[N<<2],tag[N<<2];
void build(LL rt,LL l,LL r){
    if(l==r){v[rt]=a[l];return;}
    LL mid=l+r>>1;
    build(rt<<1,l,mid);build(rt<<1|1,mid+1,r);
    v[rt]=v[rt<<1]+v[rt<<1|1];
}
void pushdown(LL rt,LL l,LL r){
    tag[rt<<1]+=tag[rt],tag[rt<<1|1]+=tag[rt];
    LL mid=l+r>>1;
    v[rt<<1]+=tag[rt]*(mid-l+1);
    v[rt<<1|1]+=tag[rt]*(r-mid);
    tag[rt]=0;
}
void update(LL rt,LL l,LL r,LL x,LL y,LL k){
    if(l>=x&&r<=y){tag[rt]+=k;v[rt]+=(r-l+1)*k;return;}
    if(tag[rt])pushdown(rt,l,r);
    LL mid=l+r>>1;
    if(x<=mid)update(rt<<1,l,mid,x,y,k);
    if(y>mid)update(rt<<1|1,mid+1,r,x,y,k);
    v[rt]=v[rt<<1]+v[rt<<1|1];
}
LL query(LL rt,LL l,LL r,LL x,LL y){
    if(x<=l&&y>=r)return v[rt];
    if(tag[rt])pushdown(rt,l,r);
    LL mid=l+r>>1,res=0;
    if(x<=mid)res+=query(rt<<1,l,mid,x,y);
    if(y>mid)res+=query(rt<<1|1,mid+1,r,x,y);
    return res;
}
int main(){
    scanf("%ld%ld",&n,&m);
    for(LL i=1;i<=n;++i)scanf("%ld",&a[i]);
    build(1,1,n);
    LL tp,x,y,z;
    while(m--){
        scanf("%ld%ld%ld",&tp,&x,&y);
        if(tp==1){
            scanf("%dl",&z);
            update(1,1,n,x,y,z);
        }else printf("%ld\n",query(1,1,n,x,y));
    }
    return 0;
}

 End

posted @ 2019-07-22 19:46  lsy263  阅读(145)  评论(0编辑  收藏  举报