zoukankan      html  css  js  c++  java
  • 线段树

    第一种写法

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #define I long long
    #define FO(i,a,b) for(R I i=a;i<=b;++i)
    #define fo(i,a,b) for(R I i=a;i<b;++i)
    #define ll long long
    #define ls(x) (x<<1)
    #define rs(x) (ls(x)|1)
    CT I N =100005;
    // CT I M = 200005;
    // const I inf = 2747483647/3;
    using namespace std;
    ll sum[N<<2];
    ll bt[N<<2];
    ll len[N<<2];
    I n,m;
    void down(I son){
        bt[ls(son)]+=bt[son];
        bt[rs(son)]+=bt[son];
        sum[ls(son)]+=bt[son]*len[ls(son)];
        sum[rs(son)]+=bt[son]*len[rs(son)];
        bt[son]=0;
    }
    void insert(I id,I v,I le=1,I re=n,I son=1) {
        if(le==re){
            sum[son]=v;
            len[son]=1;
            return ;
        }
        I mid=(le+re)>>1;
        if (id<=mid) {
            insert(id,v,le,mid,ls(son));
        } else {
            insert(id,v,mid+1,re,rs(son));
        }
        sum[son]=sum[ls(son)]+sum[rs(son)];
        len[son]=len[ls(son)]+len[rs(son)];
    }
    void add(I l,I r,I k,I le=1,I re=n,I son=1){
        if(l<=le&&re<=r){
          sum[son]+=k*len[son];
          bt[son]+=k;
          return ;
        }
        I mid=(le+re)>>1;
        down(son);
        if(l<=mid){add(l,r,k,le,mid,ls(son));}
        if(r>mid){add(l,r,k,mid+1,re,rs(son));}
        sum[son]=sum[ls(son)]+sum[rs(son)];
    }
    ll getsum(I l,I r,I le=1,I re=n,I son=1){
        if(l<=le&&re<=r){
            return sum[son];
        }
        down(son);
        I mid=(le+re)>>1;
        ll ans=0;
        if(l<=mid) ans+=getsum(l,r,le,mid,ls(son));
        if(r>mid) ans+=getsum(l,r,mid+1,re,rs(son));
        return ans;
    }
    int main(){
        scanf("%lld%lld",&n,&m);
        FO(i,1,n){
            I x;
            scanf("%lld",&x);
            insert(i,x);
        }
        FO(i,1,m){
            I x;
            scanf("%lld",&x);
            if (x==1) {
                I l,r,k;
                scanf("%lld%lld%lld",&l,&r,&k);
                add(l,r,k);
            } else {
                I l,r;
                scanf("%lld%lld",&l,&r);
                cout<<getsum(l,r)<<endl;
            }
        }
        return 0;
    }
    

    第二种写法

    #include<iostream>
    #include<cstdio>
    using namespace std;
    #define int long long
    inline int ls(int x){return x<<1;}
    inline int rs(int x){return x<<1|1;}
    struct FFF{
        int l,r;
        int sum;
        int tag;
        int mid(){return l+r>>1;}
        int len(){return r-l+1;}
    }t[100000<<2];
    int read(){
        int s,f=1;
        char ch;
        while(!isdigit(ch=getchar()))(ch=='-')&&(f=-1);
        for(s=ch-'0';isdigit(ch=getchar());s=((s+(s<<2))<<1)+ch-'0');
        return s*f;
    }
    int n,m;
    void pushup(int o){
        t[o].sum=t[ls(o)].sum+t[rs(o)].sum;
    }
    void pushdown(int o){
        int & v=t[o].tag;
        t[ls(o)].tag+=v;
        t[rs(o)].tag+=v;
        t[ls(o)].sum+=v*t[ls(o)].len();
        t[rs(o)].sum+=v*t[rs(o)].len();
        v=0;
    }
    void build(int l=1,int r=n,int o=1){
        t[o].l=l;t[o].r=r;
        if(l==r){
            t[o].sum=read();
            return;
        }
        int mid=t[o].mid();
        build(l,mid,ls(o));
        build(mid+1,r,rs(o));
        pushup(o);
    }
    void add(int l,int r,int k,int o=1){
        if(l<=t[o].l&&t[o].r<=r){
            t[o].sum+=k*t[o].len();
            t[o].tag+=k;
            return;
        }
        int mid=t[o].mid();
        pushdown(o);
        if(l<=mid){add(l,r,k,ls(o));}
        if(r>mid){add(l,r,k,rs(o));}
        pushup(o);
    }
    int getsum(int l,int r,int o=1){
        if(l<=t[o].l&&t[o].r<=r){return t[o].sum;}
        pushdown(o);
        int mid=t[o].mid();
        int ans=0;
        if(l<=mid) ans+=getsum(l,r,ls(o));
        if(r>mid) ans+=getsum(l,r,rs(o));
        return ans;
    }
    signed main(){
        n=read();m=read();
        build();
        while(m--){
            int op=read(),l=read(),r=read(),x;
            if(op==1){x=read();add(l,r,x);}
            if(op==2){cout<<getsum(l,r)<<endl;}
        }
        return 0;
    }
    

      

  • 相关阅读:
    像素图生成向量图的算法
    黑白图着色(转换成彩色图片)的算法
    JavaScript的DOM编程--12--innerHTML属性
    JavaScript的DOM编程--11--插入节点
    JavaScript的DOM编程--10--删除节点
    JavaScript的DOM编程--09--节点的替换
    js中return、return true、return false的区别
    JavaScript的DOM编程--08--复习
    JavaScript的DOM编程--07--节点的属性
    JavaScript的DOM编程--06--两个实验
  • 原文地址:https://www.cnblogs.com/eric-walker/p/9404973.html
Copyright © 2011-2022 走看看