zoukankan      html  css  js  c++  java
  • 线段树模板1

    题目链接:https://www.luogu.org/problemnew/show/P3372

    要注意的是线段树结点数组的大小应为4*n,而不是2*n。

    #include<cstdio>
    using namespace std;
    typedef long long LL;
    
    const int maxn=100005;
    
    struct node{
        int l,r;
        LL value,add;
    }tr[4*maxn];    //注意这里是4倍
    
    int n,m;
    LL a[maxn],ans;
    
    void build(int v,int l,int r){  //建立线段树
        tr[v].l=l,tr[v].r=r,tr[v].add=0;
        if(l==r){
            tr[v].value=a[r];
            return;
        }
        int mid=(l+r)>>1;
        build(2*v,l,mid);
        build(2*v+1,mid+1,r);
        tr[v].value=tr[2*v].value+tr[2*v+1].value;
    }
    
    void spread(int v){   //传递增量
        tr[2*v].value+=tr[v].add*(tr[2*v].r-tr[2*v].l+1); 
        tr[2*v+1].value+=tr[v].add*(tr[2*v+1].r-tr[2*v+1].l+1);
        tr[2*v].add+=tr[v].add;
        tr[2*v+1].add+=tr[v].add;
        tr[v].add=0;
    }
    
    void update(int v,int l,int r,LL k){   //更新
        if(tr[v].l==l&&tr[v].r==r){
            tr[v].value+=k*(r-l+1);
            tr[v].add+=k;
            return;
        }
        if(tr[v].add) spread(v);
        int mid=(tr[v].l+tr[v].r)>>1;
        if(r<=mid){
            update(2*v,l,r,k);
        }
        else{
            if(l>mid){
                update(2*v+1,l,r,k);
            }
            else{
                update(2*v,l,mid,k);
                update(2*v+1,mid+1,r,k);
            }
        }
        tr[v].value=tr[2*v].value+tr[2*v+1].value;
    }
    
    void query(int v,int l,int r){     //查询
        if(tr[v].l==l&&tr[v].r==r){
            ans+=tr[v].value;
            return;
        }
        if(tr[v].add) spread(v);
        int mid=(tr[v].l+tr[v].r)>>1;
        if(r<=mid){
            query(2*v,l,r);
        }
        else{
            if(l>mid){
                query(2*v+1,l,r);
            }
            else{
                query(2*v,l,mid);
                query(2*v+1,mid+1,r);
            }
        }
        tr[v].value=tr[2*v].value+tr[2*v+1].value;
    }
    
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i)
            scanf("%lld",&a[i]);
        build(1,1,n);
        while(m--){
            int op;
            scanf("%d",&op);
            if(op==1){
                int x,y;
                LL k;
                scanf("%d%d%lld",&x,&y,&k);
                update(1,x,y,k);
            }
            else{
                int x,y;
                scanf("%d%d",&x,&y);
                ans=0;
                query(1,x,y);
                printf("%lld
    ",ans);
            }
        }
        return 0;
    }
  • 相关阅读:
    数据库连接代码
    智能家居资源汇总
    android应用设计与实现相关资源汇总
    嵌入式设计应用资料汇总,不定时更新中……
    Zigbee相关资料大全,不断更新中……
    H.264视频编码资料汇总,不断更新……
    星网锐捷笔试
    华为 10第二题 成都 约瑟夫环
    2014华为校园招聘上机测试题目(华科提前批)
    2014年华为校招成渝地区上机试题
  • 原文地址:https://www.cnblogs.com/FrankChen831X/p/10770697.html
Copyright © 2011-2022 走看看