线段树模板

code:(洛谷P3372)

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<ctime>
using namespace std;

const int MAX=100010;
const int INF=0x3f3f3f3f;

int n,m;
long long a[MAX];

struct nodes{
    long long sum,lazy;
}node[MAX<<1+1];

void pushup(int cur){
    node[cur].sum=node[cur<<1].sum+node[cur<<1|1].sum;
}

void pushdown(int cur,int ln,int rn){
    if(node[cur].lazy){
        int c=node[cur].lazy;
        node[cur<<1].sum+=c*ln;
        node[cur<<1].lazy+=c;
        node[cur<<1|1].sum+=c*rn;
        node[cur<<1|1].lazy+=c;
        node[cur].lazy=0;
    }
}

void build(int l,int r,int cur){
    if(l==r) {
        node[cur].sum=a[l];
        return ;    
    }
    int mid=(l+r)>>1;
    build(l,mid,cur<<1);
    build(mid+1,r,cur<<1|1);
    pushup(cur);
}

void edge_update(int L,int R,int c,int l,int r,int cur){
    if(l>=L&&r<=R) {
        node[cur].sum+=c*(r-l+1);
        node[cur].lazy+=c;
        return ;
    }
    int mid=(l+r)>>1;
    pushdown(cur,mid-l+1,r-mid);
    if(L<=mid) edge_update(L,R,c,l,mid,cur<<1);
    if(R>mid) edge_update(L,R,c,mid+1,r,cur<<1|1);
    pushup(cur);
}

void point_update(int L,long long c,int l,int r,int cur){
    if(l==r) {
        node[cur].sum+=c;
        return ;
    }
    int mid=(l+r)>>1;
    if(L>mid) point_update(L,c,mid+1,r,cur<<1|1);
    else point_update(L,c,l,mid,cur<<1);
    pushup(cur);
}

long long query(int L,int R,int l,int r,int cur){
    if(L<=l&&R>=r) return node[cur].sum;
    int mid=(l+r)>>1;
    pushdown(cur,mid-l+1,r-mid);
    long long ans=0;
    if(L<=mid) ans+=query(L,R,l,mid,cur<<1);
    if(R>mid) ans+=query(L,R,mid+1,r,cur<<1|1);
    return ans;
}

void print(){
    cout<<endl;
    for(int i=1;i<=n*2;i++) 
        printf("%d ",node[i].sum);
    cout<<endl<<endl;;
}

int main(){
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
    build(1,n,1);
//  print();
    for(int i=1;i<=m;i++) {
        int c,x,y;
        scanf("%d",&c);
        if(c==1) {
            long long k;
            scanf("%d %d %lld",&x,&y,&k);
            edge_update(x,y,k,1,n,1);
//          print();
        }
        if(c==2) {
            scanf("%d %d",&x,&y);
            printf("%lld\n",query(x,y,1,n,1));
        }
    }
    return 0;
}
posted @ 2018-02-09 22:31  Menteur_hxy  阅读(79)  评论(0编辑  收藏  举报