luogu_ P3372 [template] segment tree 1

Partition plates title

#include<iostream> 
#include<cstdio>

#define ri register int
#define u long long

namespace opt {
    
    inline u in() {
        u x(0),f(1);
        char s(getchar());
        while(s<'0'||s>'9') {
            if(s=='-') f=-1;
            s=getchar();
        }
        while(s>='0'&&s<='9') {
            x=(x<<1)+(x<<3)+s-'0';
            s=getchar();
        }
        return x*f;
    }
    
}

using opt::in;

#define NN 100005

namespace fun_ki{
    
    struct node{
        u l,r,sum,add;
    }a[NN];
    
    u pos [NN], poi [NN];
    
    void update(const u &l,const u &r,const u &x){
        u p(pos[l]),q(pos[r]);
        if(p^q){
            for(ri i(p+1);i<=q-1;++i) a[i].add+=x;
            for(ri i(l);i<=a[p].r;++i) poi[i]+=x;
            for(ri i(a[q].l);i<=r;++i) poi[i]+=x;
            a[p].sum+=(a[p].r-l+1)*x,a[q].sum+=(r-a[q].l+1)*x;
        }
        else{
            for(ri i(l);i<=r;++i) poi[i]+=x;
            a[q].sum+=x*(r-l+1);
        }
    }
    
    u query(const u &l,const u &r){
        u p(pos[l]),q(pos[r]);
        u _re(0);
        if(p^q){
            for(ri i(p+1);i<=q-1;++i) _re+=a[i].sum+(a[i].r-a[i].l+1)*a[i].add;
            for(ri i(l);i<=a[p].r;++i) _re+=poi[i];
            for(ri i(a[q].l);i<=r;++i) _re+=poi[i];
            _re+=a[p].add*(a[p].r-l+1),_re+=a[q].add*(r-a[q].l+1);
        }
        else{
            for(ri i(l);i<=r;++i) _re+=poi[i];
            _re+=a[q].add*(r-l+1);
        }
        return _re;
    }
    
}

#include<cmath>

namespace mainstay {
    
    using namespace fun_ki;
    
    u N,M;
    
    inline void solve(){
        N=in(),M=in();
        for(ri i(1);i<=N;++i) poi[i]=in();
        u t(std::sqrt(N));
        for(ri i(1);i<=t;++i) a[i].l=(i-1)*t+1,a[i].r=i*t;
        if(a[t].r<N) a[++t].l=t*t+1,a[t].r=N;
        for(ri i(1);i<=t;++i){
            for(ri j(a[i].l);j<=a[i].r;++j){
                a[i].sum+=poi[j],pos[j]=i;
            }
        }
        for(ri i(1);i<=M;++i){
            u _k(in());
            if(_k==1){
                u _a(in()),_b(in()),_c(in());
                update(_a,_b,_c);
            }
            else {
                u _a(in()),_b(in());
                printf("%lld\n",query(_a,_b));
            }
        }
    }
    
}

int main () {
    
    //freopen("x.txt","r",stdin);
    //freopen("my.txt","w",stdout);
    std::ios::sync_with_stdio(false);
    mainstay::solve();
    
}

 

Guess you like

Origin www.cnblogs.com/ling-zhi/p/11797453.html