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;
    }
  • 相关阅读:
    BeanUtils.copyProperties的用法
    Eclipse中GitLab的配置和使用入门
    认识与入门 Markdown
    mybatis基础配置
    动态规划-最长公共子串
    查找
    Entity Framework Code First ---EF Power Tool 和MySql一起使用遇到的问题
    使用TortoiseSVN碰到的几个问题(2)-冲突解决, 图标重载
    使用TortoiseSVN碰到的几个问题(1)-导入,提交,更新
    Asp.net MVC4 Step By Step(5)-使用Web API
  • 原文地址:https://www.cnblogs.com/FrankChen831X/p/10770697.html
Copyright © 2011-2022 走看看