首页 > 其他 > 详细

luogu_ P3372 【模板】线段树 1

时间:2019-11-05 12:38:10      阅读:66      评论:0      收藏:0      [点我收藏+]

分块板题

#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();
    
}

 

luogu_ P3372 【模板】线段树 1

原文:https://www.cnblogs.com/ling-zhi/p/11797453.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!