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;
    }
  • 相关阅读:
    显示器面板参数
    解决SQL Server 2008安装时提示:重新启动计算机 失败
    SQL Server 的 TSQL 语句的性能评估方法
    判断字母大小写
    linux发展史简介
    下载route命令源码
    TCP糊涂窗口综合症
    QT显示中文
    TCP四个定时器 之 TCP坚持定时器
    android 去ListView滑动阴影
  • 原文地址:https://www.cnblogs.com/FrankChen831X/p/10770697.html
Copyright © 2011-2022 走看看